summaryrefslogtreecommitdiffstats
path: root/src/resolve/resolved-bus.c
diff options
context:
space:
mode:
authorDmitry Rozhkov <dmitry.rozhkov@linux.intel.com>2017-11-29 10:03:44 +0100
committerDmitry Rozhkov <dmitry.rozhkov@linux.intel.com>2017-12-08 13:29:27 +0100
commit400f54fb3666e49115dc36a585f68047370096af (patch)
tree3e209a9cfd6b8ea51b2ed4e3cd1a7b195436a026 /src/resolve/resolved-bus.c
parentresolved: consult Polkit for privileges when manipulating DNS-SD (diff)
downloadsystemd-400f54fb3666e49115dc36a585f68047370096af.tar.xz
systemd-400f54fb3666e49115dc36a585f68047370096af.zip
resolved: support multiple TXT RRs per DNS-SD service
Section 6.8 of RFC 6763 allows having service instances with multiple TXT resource records.
Diffstat (limited to 'src/resolve/resolved-bus.c')
-rw-r--r--src/resolve/resolved-bus.c87
1 files changed, 61 insertions, 26 deletions
diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c
index 7060936414..9157d9ea68 100644
--- a/src/resolve/resolved-bus.c
+++ b/src/resolve/resolved-bus.c
@@ -1605,7 +1605,6 @@ static int bus_method_register_service(sd_bus_message *message, void *userdata,
_cleanup_free_ char *instance_name = NULL;
Manager *m = userdata;
DnssdService *s = NULL;
- DnsTxtItem *last = NULL;
const char *name;
const char *name_template;
const char *type;
@@ -1669,46 +1668,82 @@ static int bus_method_register_service(sd_bus_message *message, void *userdata,
if (r < 0)
return r;
- r = sd_bus_message_enter_container(message, SD_BUS_TYPE_ARRAY, "{say}");
+ r = sd_bus_message_enter_container(message, SD_BUS_TYPE_ARRAY, "a{say}");
if (r < 0)
- return sd_bus_error_set_errno(error, r);
+ return r;
- while ((r = sd_bus_message_enter_container(message, SD_BUS_TYPE_DICT_ENTRY, "say")) > 0) {
- const char *key;
- const void *value;
- size_t size;
- DnsTxtItem *i;
+ while ((r = sd_bus_message_enter_container(message, SD_BUS_TYPE_ARRAY, "{say}")) > 0) {
+ _cleanup_(dnssd_txtdata_freep) DnssdTxtData *txt_data = NULL;
+ DnsTxtItem *last = NULL;
- r = sd_bus_message_read(message, "s", &key);
- if (r < 0)
- return sd_bus_error_set_errno(error, r);
+ txt_data = new0(DnssdTxtData, 1);
+ if (!txt_data)
+ return log_oom();
+
+ while ((r = sd_bus_message_enter_container(message, SD_BUS_TYPE_DICT_ENTRY, "say")) > 0) {
+ const char *key;
+ const void *value;
+ size_t size;
+ DnsTxtItem *i;
+
+ r = sd_bus_message_read(message, "s", &key);
+ if (r < 0)
+ return r;
+
+ if (isempty(key))
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Keys in DNS-SD TXT RRs can't be empty");
- if (strlen_ptr(key) == 0)
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Keys in DNS-SD TXT RRs can't be empty");
+ if (!ascii_is_valid(key))
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "TXT key '%s' contains non-ASCII symbols", key);
- if (!ascii_is_valid(key))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "TXT key '%s' contains non-ASCII symbols", key);
+ r = sd_bus_message_read_array(message, 'y', &value, &size);
+ if (r < 0)
+ return r;
- r = sd_bus_message_read_array(message, 'y', &value, &size);
+ r = dnssd_txt_item_new_from_data(key, value, size, &i);
+ if (r < 0)
+ return r;
+
+ LIST_INSERT_AFTER(items, txt_data->txt, last, i);
+ last = i;
+
+ r = sd_bus_message_exit_container(message);
+ if (r < 0)
+ return r;
+
+ }
if (r < 0)
- return sd_bus_error_set_errno(error, r);
+ return r;
- r = dnssd_txt_item_new_from_data(key, value, size, &i);
+ r = sd_bus_message_exit_container(message);
if (r < 0)
- return sd_bus_error_set_errno(error, r);
+ return r;
- LIST_INSERT_AFTER(items, service->txt, last, i);
- last = i;
+ if (txt_data->txt) {
+ LIST_PREPEND(items, service->txt_data_items, txt_data);
+ txt_data = NULL;
+ }
}
+ if (r < 0)
+ return r;
r = sd_bus_message_exit_container(message);
if (r < 0)
- return sd_bus_error_set_errno(error, r);
+ return r;
+
+ if (!service->txt_data_items) {
+ _cleanup_(dnssd_txtdata_freep) DnssdTxtData *txt_data = NULL;
- if (!service->txt) {
- r = dns_txt_item_new_empty(&service->txt);
+ txt_data = new0(DnssdTxtData, 1);
+ if (!txt_data)
+ return log_oom();
+
+ r = dns_txt_item_new_empty(&txt_data->txt);
if (r < 0)
- return sd_bus_error_set_errno(error, r);
+ return r;
+
+ LIST_PREPEND(items, service->txt_data_items, txt_data);
+ txt_data = NULL;
}
r = sd_bus_path_encode("/org/freedesktop/resolve1/dnssd", service->name, &path);
@@ -1804,7 +1839,7 @@ static const sd_bus_vtable resolve_vtable[] = {
SD_BUS_METHOD("SetLinkDNSSECNegativeTrustAnchors", "ias", NULL, bus_method_set_link_dnssec_negative_trust_anchors, 0),
SD_BUS_METHOD("RevertLink", "i", NULL, bus_method_revert_link, 0),
- SD_BUS_METHOD("RegisterService", "sssqqqa{say}", "o", bus_method_register_service, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("RegisterService", "sssqqqaa{say}", "o", bus_method_register_service, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("UnregisterService", "o", NULL, bus_method_unregister_service, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END,
};