summaryrefslogtreecommitdiff
path: root/src/resolve/resolved-conf.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/resolve/resolved-conf.c')
-rw-r--r--src/resolve/resolved-conf.c161
1 files changed, 160 insertions, 1 deletions
diff --git a/src/resolve/resolved-conf.c b/src/resolve/resolved-conf.c
index 3cf4261ff0..ca69d70e3c 100644
--- a/src/resolve/resolved-conf.c
+++ b/src/resolve/resolved-conf.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -21,10 +22,14 @@
#include "conf-parser.h"
#include "def.h"
#include "extract-word.h"
+#include "hexdecoct.h"
#include "parse-util.h"
#include "resolved-conf.h"
+#include "resolved-dnssd.h"
+#include "specifier.h"
#include "string-table.h"
#include "string-util.h"
+#include "utf8.h"
DEFINE_CONFIG_PARSE_ENUM(config_parse_dns_stub_listener_mode, dns_stub_listener_mode, DnsStubListenerMode, "Failed to parse DNS stub listener mode setting");
@@ -227,6 +232,160 @@ int config_parse_search_domains(
return 0;
}
+int config_parse_dnssd_service_name(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) {
+ static const Specifier specifier_table[] = {
+ { 'b', specifier_boot_id, NULL },
+ { 'H', specifier_host_name, NULL },
+ { 'm', specifier_machine_id, NULL },
+ { 'v', specifier_kernel_release, NULL },
+ {}
+ };
+ DnssdService *s = userdata;
+ _cleanup_free_ char *name = NULL;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(s);
+
+ if (isempty(rvalue)) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Service instance name can't be empty. Ignoring.");
+ return -EINVAL;
+ }
+
+ r = free_and_strdup(&s->name_template, rvalue);
+ if (r < 0)
+ return log_oom();
+
+ r = specifier_printf(s->name_template, specifier_table, NULL, &name);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to replace specifiers: %m");
+
+ if (!dns_service_name_is_valid(name)) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Service instance name template renders to invalid name '%s'. Ignoring.", name);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int config_parse_dnssd_service_type(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) {
+ DnssdService *s = userdata;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(s);
+
+ if (isempty(rvalue)) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Service type can't be empty. Ignoring.");
+ return -EINVAL;
+ }
+
+ if (!dnssd_srv_type_is_valid(rvalue)) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Service type is invalid. Ignoring.");
+ return -EINVAL;
+ }
+
+ r = free_and_strdup(&s->type, rvalue);
+ if (r < 0)
+ return log_oom();
+
+ return 0;
+}
+
+int config_parse_dnssd_txt(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) {
+ _cleanup_(dnssd_txtdata_freep) DnssdTxtData *txt_data = NULL;
+ DnssdService *s = userdata;
+ DnsTxtItem *last = NULL;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(s);
+
+ if (isempty(rvalue)) {
+ /* Flush out collected items */
+ s->txt_data_items = dnssd_txtdata_free_all(s->txt_data_items);
+ return 0;
+ }
+
+ txt_data = new0(DnssdTxtData, 1);
+ if (!txt_data)
+ return log_oom();
+
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
+ _cleanup_free_ char *key = NULL;
+ _cleanup_free_ char *value = NULL;
+ _cleanup_free_ void *decoded = NULL;
+ size_t length = 0;
+ DnsTxtItem *i;
+ int r;
+
+ r = extract_first_word(&rvalue, &word, NULL,
+ EXTRACT_QUOTES|EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX);
+ if (r == 0)
+ break;
+ if (r == -ENOMEM)
+ return log_oom();
+ if (r < 0)
+ return log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax, ignoring: %s", rvalue);
+
+ r = split_pair(word, "=", &key, &value);
+ if (r == -ENOMEM)
+ return log_oom();
+ if (r == -EINVAL) {
+ key = word;
+ word = NULL;
+ }
+
+ if (!ascii_is_valid(key)) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid syntax, ignoring: %s", key);
+ return -EINVAL;
+ }
+
+ switch (ltype) {
+
+ case DNS_TXT_ITEM_DATA:
+ if (value) {
+ r = unbase64mem(value, strlen(value), &decoded, &length);
+ if (r == -ENOMEM)
+ return log_oom();
+ if (r < 0)
+ return log_syntax(unit, LOG_ERR, filename, line, r,
+ "Invalid base64 encoding, ignoring: %s", value);
+ }
+
+ r = dnssd_txt_item_new_from_data(key, decoded, length, &i);
+ if (r < 0)
+ return log_oom();
+ break;
+
+ case DNS_TXT_ITEM_TEXT:
+ r = dnssd_txt_item_new_from_string(key, value, &i);
+ if (r < 0)
+ return log_oom();
+ break;
+
+ default:
+ assert_not_reached("Unknown type of Txt config");
+ }
+
+ LIST_INSERT_AFTER(items, txt_data->txt, last, i);
+ last = i;
+ }
+
+ if (!LIST_IS_EMPTY(txt_data->txt)) {
+ LIST_PREPEND(items, s->txt_data_items, txt_data);
+ txt_data = NULL;
+ }
+
+ return 0;
+}
+
int manager_parse_config_file(Manager *m) {
int r;
@@ -236,7 +395,7 @@ int manager_parse_config_file(Manager *m) {
CONF_PATHS_NULSTR("systemd/resolved.conf.d"),
"Resolve\0",
config_item_perf_lookup, resolved_gperf_lookup,
- false, m);
+ CONFIG_PARSE_WARN, m);
if (r < 0)
return r;