resolved-dns-rr.c revision f2af5ea3cbf54998ed41d2d21a3448abb92ca7ff
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering This file is part of systemd.
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering Copyright 2014 Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering systemd is free software; you can redistribute it and/or modify it
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering under the terms of the GNU Lesser General Public License as published by
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering (at your option) any later version.
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering systemd is distributed in the hope that it will be useful, but
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering Lesser General Public License for more details.
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering You should have received a copy of the GNU Lesser General Public License
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart PoetteringDnsResourceKey* dns_resource_key_new(uint16_t class, uint16_t type, const char *name) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering k = malloc0(sizeof(DnsResourceKey) + l + 1);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering strcpy((char*) k + sizeof(DnsResourceKey), name);
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-SzmekDnsResourceKey* dns_resource_key_new_redirect(const DnsResourceKey *key, const DnsResourceRecord *cname) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(IN_SET(cname->key->type, DNS_TYPE_CNAME, DNS_TYPE_DNAME));
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return dns_resource_key_new(key->class, key->type, cname->cname.name);
39883f622f392d8579f4428fc5a789a102efbb10Lennart Poettering r = dns_name_change_suffix(DNS_RESOURCE_KEY_NAME(key), DNS_RESOURCE_KEY_NAME(cname->key), cname->dname.name, &destination);
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek return dns_resource_key_ref((DnsResourceKey*) key);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering k = dns_resource_key_new_consume(key->class, key->type, destination);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringint dns_resource_key_new_append_suffix(DnsResourceKey **ret, DnsResourceKey *key, char *name) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering r = dns_name_concat(DNS_RESOURCE_KEY_NAME(key), name, &joined);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering new_key = dns_resource_key_new_consume(key->class, key->type, joined);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart PoetteringDnsResourceKey* dns_resource_key_new_consume(uint16_t class, uint16_t type, char *name) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart PoetteringDnsResourceKey* dns_resource_key_ref(DnsResourceKey *k) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering /* Static/const keys created with DNS_RESOURCE_KEY_CONST will
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering * set this to -1, they should not be reffed/unreffed */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart PoetteringDnsResourceKey* dns_resource_key_unref(DnsResourceKey *k) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringbool dns_resource_key_is_address(const DnsResourceKey *key) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering /* Check if this is an A or AAAA resource key */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return key->class == DNS_CLASS_IN && IN_SET(key->type, DNS_TYPE_A, DNS_TYPE_AAAA);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringint dns_resource_key_equal(const DnsResourceKey *a, const DnsResourceKey *b) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering r = dns_name_equal(DNS_RESOURCE_KEY_NAME(a), DNS_RESOURCE_KEY_NAME(b));
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringint dns_resource_key_match_rr(const DnsResourceKey *key, DnsResourceRecord *rr, const char *search_domain) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering /* Checks if an rr matches the specified key. If a search
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering * domain is specified, it will also be checked if the key
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering * with the search domain suffixed might match the RR. */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (rr->key->class != key->class && key->class != DNS_CLASS_ANY)
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett if (rr->key->type != key->type && key->type != DNS_TYPE_ANY)
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett r = dns_name_equal(DNS_RESOURCE_KEY_NAME(rr->key), DNS_RESOURCE_KEY_NAME(key));
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett r = dns_name_concat(DNS_RESOURCE_KEY_NAME(key), search_domain, &joined);
c7fdf44d08e1217d40dc092fb90a65978a0f541fLennart Poettering return dns_name_equal(DNS_RESOURCE_KEY_NAME(rr->key), joined);
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächlerint dns_resource_key_match_cname_or_dname(const DnsResourceKey *key, const DnsResourceKey *cname, const char *search_domain) {
4cd2b2cf8ca585d15ebc859701b346658262b5bbDenis Tikhomirov if (cname->class != key->class && key->class != DNS_CLASS_ANY)
0c9d8f1d4b5018199cb5a9b57580dc1480a7f915Jani Nikula r = dns_name_equal(DNS_RESOURCE_KEY_NAME(key), DNS_RESOURCE_KEY_NAME(cname));
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler r = dns_name_endswith(DNS_RESOURCE_KEY_NAME(key), DNS_RESOURCE_KEY_NAME(cname));
4cd2b2cf8ca585d15ebc859701b346658262b5bbDenis Tikhomirov r = dns_name_concat(DNS_RESOURCE_KEY_NAME(key), search_domain, &joined);
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett return dns_name_equal(joined, DNS_RESOURCE_KEY_NAME(cname));
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett return dns_name_endswith(joined, DNS_RESOURCE_KEY_NAME(cname));
0c9d8f1d4b5018199cb5a9b57580dc1480a7f915Jani Nikulaint dns_resource_key_match_soa(const DnsResourceKey *key, const DnsResourceKey *soa) {
0c9d8f1d4b5018199cb5a9b57580dc1480a7f915Jani Nikula /* Checks whether 'soa' is a SOA record for the specified key. */
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering return dns_name_endswith(DNS_RESOURCE_KEY_NAME(key), DNS_RESOURCE_KEY_NAME(soa));
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poetteringstatic void dns_resource_key_hash_func(const void *i, struct siphash *state) {
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering dns_name_hash_func(DNS_RESOURCE_KEY_NAME(k), state);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering siphash24_compress(&k->class, sizeof(k->class), state);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering siphash24_compress(&k->type, sizeof(k->type), state);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poetteringstatic int dns_resource_key_compare_func(const void *a, const void *b) {
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering const DnsResourceKey *x = a, *y = b;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering ret = dns_name_compare_func(DNS_RESOURCE_KEY_NAME(x), DNS_RESOURCE_KEY_NAME(y));
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringconst struct hash_ops dns_resource_key_hash_ops = {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringint dns_resource_key_to_string(const DnsResourceKey *key, char **ret) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering char cbuf[strlen("CLASS") + DECIMAL_STR_MAX(uint16_t)], tbuf[strlen("TYPE") + DECIMAL_STR_MAX(uint16_t)];
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering const char *c, *t, *n;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering /* If we cannot convert the CLASS/TYPE into a known string,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering use the format recommended by RFC 3597, Section 5. */
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek t = dns_type_to_string(key->type);
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler if (asprintf(&s, "%s%s %s %-5s", n, endswith(n, ".") ? "" : ".", c, t) < 0)
be3f52f4ed02a9256b1577719677b32a17b525acLennart PoetteringDnsResourceRecord* dns_resource_record_new(DnsResourceKey *key) {
be3f52f4ed02a9256b1577719677b32a17b525acLennart PoetteringDnsResourceRecord* dns_resource_record_new_full(uint16_t class, uint16_t type, const char *name) {
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering key = dns_resource_key_new(class, type, name);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart PoetteringDnsResourceRecord* dns_resource_record_ref(DnsResourceRecord *rr) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart PoetteringDnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr) {
case DNS_TYPE_RRSIG:
case DNS_TYPE_NSEC:
case DNS_TYPE_NSEC3:
case DNS_TYPE_LOC:
case DNS_TYPE_A:
case DNS_TYPE_AAAA:
return NULL;
int dns_resource_record_new_reverse(DnsResourceRecord **ret, int family, const union in_addr_union *address, const char *hostname) {
if (!key)
return -ENOMEM;
if (!rr)
return -ENOMEM;
return -ENOMEM;
int dns_resource_record_new_address(DnsResourceRecord **ret, int family, const union in_addr_union *address, const char *name) {
if (!rr)
return -ENOMEM;
if (!rr)
return -ENOMEM;
return -EAFNOSUPPORT;
assert(a);
assert(b);
case DNS_TYPE_SRV:
case DNS_TYPE_PTR:
case DNS_TYPE_NS:
case DNS_TYPE_CNAME:
case DNS_TYPE_DNAME:
case DNS_TYPE_HINFO:
case DNS_TYPE_TXT:
case DNS_TYPE_A:
case DNS_TYPE_AAAA:
case DNS_TYPE_SOA:
case DNS_TYPE_MX:
case DNS_TYPE_LOC:
case DNS_TYPE_DS:
case DNS_TYPE_SSHFP:
case DNS_TYPE_DNSKEY:
case DNS_TYPE_RRSIG:
case DNS_TYPE_NSEC:
case DNS_TYPE_NSEC3:
memcmp(a->nsec3.next_hashed_name, b->nsec3.next_hashed_name, a->nsec3.next_hashed_name_size) == 0 &&
NS,
EW,
return NULL;
return -EINVAL;
return -EINVAL;
Iterator i;
unsigned type;
return NULL;
return NULL;
return NULL;
if (!str)
return NULL;
DnsTxtItem *i;
p = s = new(char, c);
return NULL;
size_t j;
if (i != first)
for (j = 0; j < i->length; j++) {
*(p++) = i->data[j];
return NULL;
case DNS_TYPE_SRV:
return NULL;
case DNS_TYPE_PTR:
case DNS_TYPE_NS:
case DNS_TYPE_CNAME:
case DNS_TYPE_DNAME:
return NULL;
case DNS_TYPE_HINFO:
return NULL;
case DNS_TYPE_TXT:
return NULL;
return NULL;
case DNS_TYPE_A: {
return NULL;
return NULL;
case DNS_TYPE_AAAA:
return NULL;
return NULL;
case DNS_TYPE_SOA:
return NULL;
case DNS_TYPE_MX:
return NULL;
case DNS_TYPE_LOC:
return NULL;
return NULL;
case DNS_TYPE_DS:
return NULL;
return NULL;
case DNS_TYPE_SSHFP:
return NULL;
return NULL;
case DNS_TYPE_DNSKEY: {
const char *alg;
return NULL;
return NULL;
case DNS_TYPE_RRSIG: {
return NULL;
return NULL;
return NULL;
* http://tools.ietf.org/html/rfc3597#section-5 */
return NULL;
case DNS_TYPE_NSEC:
return NULL;
return NULL;
case DNS_TYPE_NSEC3: {
if (!salt)
return NULL;
if (!hash)
return NULL;
return NULL;
hash,
return NULL;
return NULL;
return NULL;
.on_stack = true,
.refuse_compression = true,
DnsTxtItem *n;
return NULL;
n = i->items_next;
free(i);
return dns_txt_item_free_all(n);
/* Mnemonics as listed on https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml */
/* Names as listed on https://www.iana.org/assignments/ds-rr-types/ds-rr-types.xhtml */