/* Trailing dash */
return -EINVAL;
- if (*n == '.')
+ if (n[0] == '.' && (n[1] != 0 || !FLAGS_SET(flags, DNS_LABEL_LEAVE_TRAILING_DOT)))
n++;
+
break;
}
return -EINVAL;
/* More than one trailing dot? */
- if (*n == '.')
+ if (n[0] == '.' && !FLAGS_SET(flags, DNS_LABEL_LEAVE_TRAILING_DOT))
return -EINVAL;
if (sz >= 1 && d)
return dns_name_is_valid(name);
}
+
+int dns_name_dot_suffixed(const char *name) {
+ const char *p = name;
+ int r;
+
+ for (;;) {
+ if (streq(p, "."))
+ return true;
+
+ r = dns_label_unescape(&p, NULL, DNS_LABEL_MAX, DNS_LABEL_LEAVE_TRAILING_DOT);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return false;
+ }
+}
#define DNS_N_LABELS_MAX 127
typedef enum DNSLabelFlags {
- DNS_LABEL_LDH = 1 << 0, /* Follow the "LDH" rule — only letters, digits, and internal hyphens. */
- DNS_LABEL_NO_ESCAPES = 1 << 1, /* Do not treat backslashes specially */
+ DNS_LABEL_LDH = 1 << 0, /* Follow the "LDH" rule — only letters, digits, and internal hyphens. */
+ DNS_LABEL_NO_ESCAPES = 1 << 1, /* Do not treat backslashes specially */
+ DNS_LABEL_LEAVE_TRAILING_DOT = 1 << 2, /* Leave trailing dot in place */
} DNSLabelFlags;
int dns_label_unescape(const char **name, char *dest, size_t sz, DNSLabelFlags flags);
int dns_name_apply_idna(const char *name, char **ret);
int dns_name_is_valid_or_address(const char *name);
+
+int dns_name_dot_suffixed(const char *name);
assert_se(dns_name_is_valid_or_address("::1") > 0);
}
+static void test_dns_name_dot_suffixed(void) {
+ log_info("/* %s */", __func__);
+
+ assert_se(dns_name_dot_suffixed("") == 0);
+ assert_se(dns_name_dot_suffixed(".") > 0);
+ assert_se(dns_name_dot_suffixed("foo") == 0);
+ assert_se(dns_name_dot_suffixed("foo.") > 0);
+ assert_se(dns_name_dot_suffixed("foo\\..") > 0);
+ assert_se(dns_name_dot_suffixed("foo\\.") == 0);
+ assert_se(dns_name_dot_suffixed("foo.bar.") > 0);
+ assert_se(dns_name_dot_suffixed("foo.bar\\.\\.\\..") > 0);
+ assert_se(dns_name_dot_suffixed("foo.bar\\.\\.\\.\\.") == 0);
+}
+
int main(int argc, char *argv[]) {
test_setup_logging(LOG_DEBUG);
test_dns_name_common_suffix();
test_dns_name_apply_idna();
test_dns_name_is_valid_or_address();
+ test_dns_name_dot_suffixed();
return 0;
}