diff options
author | Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com> | 2017-11-29 10:03:44 +0100 |
---|---|---|
committer | Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com> | 2017-12-08 13:29:27 +0100 |
commit | 400f54fb3666e49115dc36a585f68047370096af (patch) | |
tree | 3e209a9cfd6b8ea51b2ed4e3cd1a7b195436a026 /src/resolve/resolved-bus.c | |
parent | resolved: consult Polkit for privileges when manipulating DNS-SD (diff) | |
download | systemd-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.c | 87 |
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, }; |