summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaan De Meyer <daan.j.demeyer@gmail.com>2021-01-23 17:33:24 +0000
committerDaan De Meyer <daan.j.demeyer@gmail.com>2021-01-30 13:51:41 +0000
commit69988fee43302545113c6fd9241b1e65eb2fc491 (patch)
treee7f15852eae4ef6203bc86729fa654b345a29f43
parentd8067d40412935e5a317181fb5ea8365819271a1 (diff)
downloadsystemd-69988fee43302545113c6fd9241b1e65eb2fc491.tar.gz
resolve: Add GetMulticastHosts() D-Bus method
GetMulticastHosts() returns an array of hostnames/addresses discovered via LLMNR or Multicast DNS. It does not trigger any discovery on its own. Instead, it simply returns whatever is already in resolved's cache.
-rw-r--r--man/org.freedesktop.resolve1.xml5
-rw-r--r--src/resolve/resolved-bus.c99
-rw-r--r--src/resolve/resolved-dns-cache.c50
-rw-r--r--src/resolve/resolved-dns-cache.h3
-rw-r--r--src/resolve/resolved-dns-scope.c2
5 files changed, 146 insertions, 13 deletions
diff --git a/man/org.freedesktop.resolve1.xml b/man/org.freedesktop.resolve1.xml
index 860a14877d..9036f7d11f 100644
--- a/man/org.freedesktop.resolve1.xml
+++ b/man/org.freedesktop.resolve1.xml
@@ -115,6 +115,7 @@ node /org/freedesktop/resolve1 {
ResetStatistics();
FlushCaches();
ResetServerFeatures();
+ GetMulticastHosts(out a(stiiay) UNNAMED);
properties:
readonly s LLMNRHostname = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
@@ -164,6 +165,8 @@ node /org/freedesktop/resolve1 {
<!--method ResetServerFeatures is not documented!-->
+ <!--method GetMulticastHosts is not documented!-->
+
<!--property DNSSECNegativeTrustAnchors is not documented!-->
<!--Autogenerated cross-references for systemd.directives, do not edit-->
@@ -212,6 +215,8 @@ node /org/freedesktop/resolve1 {
<variablelist class="dbus-method" generated="True" extra-ref="ResetServerFeatures()"/>
+ <variablelist class="dbus-method" generated="True" extra-ref="GetMulticastHosts()"/>
+
<variablelist class="dbus-property" generated="True" extra-ref="LLMNRHostname"/>
<variablelist class="dbus-property" generated="True" extra-ref="LLMNR"/>
diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c
index dd27c50b49..49e23ae450 100644
--- a/src/resolve/resolved-bus.c
+++ b/src/resolve/resolved-bus.c
@@ -132,15 +132,17 @@ static int reply_query_state(DnsQuery *q) {
}
}
-static int append_address(sd_bus_message *reply, DnsResourceRecord *rr, int ifindex) {
+static int append_address(sd_bus_message *reply, DnsResourceRecord *rr, int ifindex, bool is_container) {
int r;
assert(reply);
assert(rr);
- r = sd_bus_message_open_container(reply, 'r', "iiay");
- if (r < 0)
- return r;
+ if (is_container) {
+ r = sd_bus_message_open_container(reply, 'r', "iiay");
+ if (r < 0)
+ return r;
+ }
r = sd_bus_message_append(reply, "i", ifindex);
if (r < 0)
@@ -165,9 +167,11 @@ static int append_address(sd_bus_message *reply, DnsResourceRecord *rr, int ifin
if (r < 0)
return r;
- r = sd_bus_message_close_container(reply);
- if (r < 0)
- return r;
+ if (is_container) {
+ r = sd_bus_message_close_container(reply);
+ if (r < 0)
+ return r;
+ }
return 0;
}
@@ -216,7 +220,7 @@ static void bus_method_resolve_hostname_complete(DnsQuery *q) {
if (r == 0)
continue;
- r = append_address(reply, rr, ifindex);
+ r = append_address(reply, rr, ifindex, true);
if (r < 0)
goto finish;
@@ -851,7 +855,7 @@ static int append_srv(DnsQuery *q, sd_bus_message *reply, DnsResourceRecord *rr)
if (r == 0)
continue;
- r = append_address(reply, zz, ifindex);
+ r = append_address(reply, zz, ifindex, true);
if (r < 0)
return r;
}
@@ -2000,6 +2004,76 @@ static int bus_method_unregister_service(sd_bus_message *message, void *userdata
return call_dnssd_method(m, message, bus_dnssd_method_unregister, error);
}
+static int bus_method_get_multicast_hosts(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ DnsScope *s;
+ Manager *m = userdata;
+ int r;
+
+ assert(message);
+ assert(m);
+
+ r = sd_bus_message_new_method_return(message, &reply);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_open_container(reply, 'a', "(stiiay)");
+ if (r < 0)
+ return r;
+
+ LIST_FOREACH(scopes, s, m->dns_scopes) {
+ _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
+ DnsResourceRecord *rr;
+ DnsAnswerFlags flags;
+ int ifindex;
+
+ if (s->protocol == DNS_PROTOCOL_DNS)
+ continue;
+
+ r = dns_cache_dump_to_answer(&s->cache, &answer);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ continue;
+
+ DNS_ANSWER_FOREACH_FULL(rr, ifindex, flags, answer) {
+ _cleanup_free_ char *normalized = NULL;
+ bool authenticated = FLAGS_SET(flags, DNS_ANSWER_AUTHENTICATED);
+
+ r = dns_name_normalize(dns_resource_key_name(rr->key), 0, &normalized);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_open_container(reply, 'r', "stiiay");
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_append(
+ reply,
+ "st",
+ normalized,
+ SD_RESOLVED_FLAGS_MAKE(s->protocol, s->family, authenticated));
+ if (r < 0)
+ return r;
+
+ r = append_address(reply, rr, ifindex, false);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_close_container(reply);
+ if (r < 0)
+ return r;
+ }
+ }
+
+ r = sd_bus_message_close_container(reply);
+ if (r < 0)
+ return r;
+
+ return sd_bus_reply(message, reply);
+}
+
+/* clang-format off */
static const sd_bus_vtable resolve_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("LLMNRHostname", "s", NULL, offsetof(Manager, llmnr_hostname), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
@@ -2138,9 +2212,14 @@ static const sd_bus_vtable resolve_vtable[] = {
SD_BUS_NO_RESULT,
bus_method_reset_server_features,
SD_BUS_VTABLE_UNPRIVILEGED),
-
+ SD_BUS_METHOD_WITH_ARGS("GetMulticastHosts",
+ SD_BUS_NO_ARGS,
+ SD_BUS_RESULT("a(stiiay)", addresses),
+ bus_method_get_multicast_hosts,
+ SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END,
};
+/* clang-format on */
const BusObjectImplementation manager_object = {
"/org/freedesktop/resolve1",
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
index 75f1ccb649..e199e8f00c 100644
--- a/src/resolve/resolved-dns-cache.c
+++ b/src/resolve/resolved-dns-cache.c
@@ -1066,7 +1066,55 @@ int dns_cache_export_shared_to_packet(DnsCache *cache, DnsPacket *p) {
return 0;
}
-void dns_cache_dump(DnsCache *cache, FILE *f) {
+int dns_cache_dump_to_answer(DnsCache *cache, DnsAnswer **ret) {
+ _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
+ DnsCacheItem *i;
+ size_t n = 0;
+ int r;
+
+ assert(cache);
+ assert(ret);
+
+ HASHMAP_FOREACH(i, cache->by_key) {
+ DnsCacheItem *j;
+
+ LIST_FOREACH(by_key, j, i) {
+ if (!j->rr)
+ continue;
+
+ n++;
+ }
+ }
+
+ if (n == 0) {
+ *ret = NULL;
+ return 0;
+ }
+
+ answer = dns_answer_new(n);
+ if (!answer)
+ return -ENOMEM;
+
+ HASHMAP_FOREACH(i, cache->by_key) {
+ DnsCacheItem *j;
+
+ LIST_FOREACH(by_key, j, i) {
+ if (!j->rr)
+ continue;
+
+ r = dns_answer_add(
+ answer, j->rr, j->ifindex, j->authenticated ? DNS_ANSWER_AUTHENTICATED : 0);
+ if (r < 0)
+ return r;
+ }
+ }
+
+ *ret = TAKE_PTR(answer);
+
+ return n;
+}
+
+void dns_cache_dump_to_file(DnsCache *cache, FILE *f) {
DnsCacheItem *i;
if (!cache)
diff --git a/src/resolve/resolved-dns-cache.h b/src/resolve/resolved-dns-cache.h
index 4ab213dc9c..6de44cfd05 100644
--- a/src/resolve/resolved-dns-cache.h
+++ b/src/resolve/resolved-dns-cache.h
@@ -27,7 +27,8 @@ int dns_cache_lookup(DnsCache *c, DnsResourceKey *key, bool clamp_ttl, int *rcod
int dns_cache_check_conflicts(DnsCache *cache, DnsResourceRecord *rr, int owner_family, const union in_addr_union *owner_address);
-void dns_cache_dump(DnsCache *cache, FILE *f);
+void dns_cache_dump_to_file(DnsCache *cache, FILE *f);
+int dns_cache_dump_to_answer(DnsCache *cache, DnsAnswer **answer);
bool dns_cache_is_empty(DnsCache *cache);
unsigned dns_cache_size(DnsCache *cache);
diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c
index d77e81ae39..d27a19145f 100644
--- a/src/resolve/resolved-dns-scope.c
+++ b/src/resolve/resolved-dns-scope.c
@@ -1159,7 +1159,7 @@ void dns_scope_dump(DnsScope *s, FILE *f) {
if (!dns_cache_is_empty(&s->cache)) {
fputs("CACHE:\n", f);
- dns_cache_dump(&s->cache, f);
+ dns_cache_dump_to_file(&s->cache, f);
}
}