mirror of
https://github.com/systemd/systemd.git
synced 2024-10-31 16:21:26 +03:00
resolved: add dns_resource_record_get_cname_target() helper
This determines the redirection target from a CNAME or DNAME RR given it matches some given RR key.
This commit is contained in:
parent
990e7e87ad
commit
d1f8fbea9f
@ -1722,6 +1722,7 @@ int dns_resource_record_clamp_ttl(DnsResourceRecord **rr, uint32_t max_ttl) {
|
||||
}
|
||||
|
||||
bool dns_resource_record_is_link_local_address(DnsResourceRecord *rr) {
|
||||
assert(rr);
|
||||
|
||||
if (rr->key->class != DNS_CLASS_IN)
|
||||
return false;
|
||||
@ -1735,6 +1736,47 @@ bool dns_resource_record_is_link_local_address(DnsResourceRecord *rr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int dns_resource_record_get_cname_target(DnsResourceKey *key, DnsResourceRecord *cname, char **ret) {
|
||||
_cleanup_free_ char *d = NULL;
|
||||
int r;
|
||||
|
||||
assert(key);
|
||||
assert(cname);
|
||||
|
||||
if (key->class != cname->key->class && key->class != DNS_CLASS_ANY)
|
||||
return -EUNATCH;
|
||||
|
||||
if (cname->key->type == DNS_TYPE_CNAME) {
|
||||
r = dns_name_equal(dns_resource_key_name(key),
|
||||
dns_resource_key_name(cname->key));
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return -EUNATCH; /* CNAME RR key doesn't actually match the original key */
|
||||
|
||||
d = strdup(cname->cname.name);
|
||||
if (!d)
|
||||
return -ENOMEM;
|
||||
|
||||
} else if (cname->key->type == DNS_TYPE_DNAME) {
|
||||
|
||||
r = dns_name_change_suffix(
|
||||
dns_resource_key_name(key),
|
||||
dns_resource_key_name(cname->key),
|
||||
cname->dname.name,
|
||||
&d);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return -EUNATCH; /* DNAME RR key doesn't actually match the original key */
|
||||
|
||||
} else
|
||||
return -EUNATCH; /* Not a CNAME/DNAME RR, hence doesn't match the proposition either */
|
||||
|
||||
*ret = TAKE_PTR(d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DnsTxtItem *dns_txt_item_free_all(DnsTxtItem *i) {
|
||||
DnsTxtItem *n;
|
||||
|
||||
|
@ -326,6 +326,8 @@ int dns_resource_record_clamp_ttl(DnsResourceRecord **rr, uint32_t max_ttl);
|
||||
|
||||
bool dns_resource_record_is_link_local_address(DnsResourceRecord *rr);
|
||||
|
||||
int dns_resource_record_get_cname_target(DnsResourceKey *key, DnsResourceRecord *cname, char **ret);
|
||||
|
||||
DnsTxtItem *dns_txt_item_free_all(DnsTxtItem *i);
|
||||
bool dns_txt_item_equal(DnsTxtItem *a, DnsTxtItem *b);
|
||||
DnsTxtItem *dns_txt_item_copy(DnsTxtItem *i);
|
||||
|
@ -90,6 +90,39 @@ static void test_packet_from_file(const char* filename, bool canonical) {
|
||||
}
|
||||
}
|
||||
|
||||
static void test_dns_resource_record_get_cname_target(void) {
|
||||
_cleanup_(dns_resource_record_unrefp) DnsResourceRecord *cname = NULL;
|
||||
_cleanup_free_ char *target = NULL;
|
||||
|
||||
assert_se(cname = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_CNAME, "quux.foobar"));
|
||||
assert_se(cname->cname.name = strdup("wuff.wuff"));
|
||||
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, "waldo"), cname, &target) == -EUNATCH);
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, "foobar"), cname, &target) == -EUNATCH);
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, "quux"), cname, &target) == -EUNATCH);
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, ""), cname, &target) == -EUNATCH);
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, "."), cname, &target) == -EUNATCH);
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, "nope.quux.foobar"), cname, &target) == -EUNATCH);
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, "quux.foobar"), cname, &target) == 0);
|
||||
assert_se(streq(target, "wuff.wuff"));
|
||||
target = mfree(target);
|
||||
|
||||
assert_se(cname = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNAME, "quux.foobar"));
|
||||
assert_se(cname->dname.name = strdup("wuff.wuff"));
|
||||
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, "waldo"), cname, &target) == -EUNATCH);
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, "foobar"), cname, &target) == -EUNATCH);
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, "quux"), cname, &target) == -EUNATCH);
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, ""), cname, &target) == -EUNATCH);
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, "."), cname, &target) == -EUNATCH);
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, "yupp.quux.foobar"), cname, &target) == 0);
|
||||
assert_se(streq(target, "yupp.wuff.wuff"));
|
||||
target = mfree(target);
|
||||
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, "quux.foobar"), cname, &target) == 0);
|
||||
assert_se(streq(target, "wuff.wuff"));
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int i, N;
|
||||
_cleanup_globfree_ glob_t g = {};
|
||||
@ -116,5 +149,7 @@ int main(int argc, char **argv) {
|
||||
puts("");
|
||||
}
|
||||
|
||||
test_dns_resource_record_get_cname_target();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user