X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fresolve%2Fresolved-dns-rr.c;h=c792deda47d6e19bb27dfc05ff04a5e21b127c50;hb=bd8f65387673e29f46136a4ed172097035002c23;hp=7d1cfe4aae2b8ef5f266603aa875f0fc4eebffa4;hpb=23432a1c249b9c513e438bffe9778a7ce2ee74fe;p=elogind.git diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c index 7d1cfe4aa..c792deda4 100644 --- a/src/resolve/resolved-dns-rr.c +++ b/src/resolve/resolved-dns-rr.c @@ -25,6 +25,8 @@ #include "resolved-dns-domain.h" #include "resolved-dns-rr.h" +#include "resolved-dns-packet.h" +#include "dns-type.h" DnsResourceKey* dns_resource_key_new(uint16_t class, uint16_t type, const char *name) { DnsResourceKey *k; @@ -268,6 +270,15 @@ DnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr) { free(rr->sshfp.key); break; + case DNS_TYPE_DNSKEY: + free(rr->dnskey.key); + break; + + case DNS_TYPE_RRSIG: + free(rr->rrsig.signer); + free(rr->rrsig.signature); + break; + case DNS_TYPE_LOC: case DNS_TYPE_A: case DNS_TYPE_AAAA: @@ -405,6 +416,28 @@ int dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecor a->sshfp.key_size == b->sshfp.key_size && memcmp(a->sshfp.key, b->sshfp.key, a->sshfp.key_size) == 0; + case DNS_TYPE_DNSKEY: + return a->dnskey.zone_key_flag == b->dnskey.zone_key_flag && + a->dnskey.sep_flag == b->dnskey.sep_flag && + a->dnskey.algorithm == b->dnskey.algorithm && + a->dnskey.key_size == b->dnskey.key_size && + memcmp(a->dnskey.key, b->dnskey.key, a->dnskey.key_size) == 0; + + case DNS_TYPE_RRSIG: + /* do the fast comparisons first */ + if (a->rrsig.type_covered != a->rrsig.type_covered || + a->rrsig.algorithm != a->rrsig.algorithm || + a->rrsig.labels != a->rrsig.labels || + a->rrsig.original_ttl != a->rrsig.original_ttl || + a->rrsig.expiration != a->rrsig.expiration || + a->rrsig.inception != a->rrsig.inception || + a->rrsig.key_tag != a->rrsig.key_tag || + a->rrsig.signature_size != b->rrsig.signature_size || + memcmp(a->rrsig.signature, b->rrsig.signature, a->rrsig.signature_size) != 0) + return false; + + return dns_name_equal(a->rrsig.signer, b->rrsig.signer); + default: return a->generic.size == b->generic.size && memcmp(a->generic.data, b->generic.data, a->generic.size) == 0; @@ -443,7 +476,7 @@ static char* format_location(uint32_t latitude, uint32_t longitude, uint32_t alt } int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) { - _cleanup_free_ char *k = NULL; + _cleanup_free_ char *k = NULL, *t = NULL; char *s; int r; @@ -483,9 +516,7 @@ int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) { break; case DNS_TYPE_SPF: /* exactly the same as TXT */ - case DNS_TYPE_TXT: { - _cleanup_free_ char *t; - + case DNS_TYPE_TXT: t = strv_join_quoted(rr->txt.strings); if (!t) return -ENOMEM; @@ -495,7 +526,6 @@ int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) { return -ENOMEM; break; - } case DNS_TYPE_A: { _cleanup_free_ char *x = NULL; @@ -510,18 +540,15 @@ int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) { break; } - case DNS_TYPE_AAAA: { - _cleanup_free_ char *x = NULL; - - r = in_addr_to_string(AF_INET6, (const union in_addr_union*) &rr->aaaa.in6_addr, &x); + case DNS_TYPE_AAAA: + r = in_addr_to_string(AF_INET6, (const union in_addr_union*) &rr->aaaa.in6_addr, &t); if (r < 0) return r; - s = strjoin(k, " ", x, NULL); + s = strjoin(k, " ", t, NULL); if (!s) return -ENOMEM; break; - } case DNS_TYPE_SOA: r = asprintf(&s, "%s %s %s %u %u %u %u %u", @@ -546,55 +573,98 @@ int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) { return -ENOMEM; break; - case DNS_TYPE_LOC: { - _cleanup_free_ char *loc; + case DNS_TYPE_LOC: assert(rr->loc.version == 0); - loc = format_location(rr->loc.latitude, - rr->loc.longitude, - rr->loc.altitude, - rr->loc.size, - rr->loc.horiz_pre, - rr->loc.vert_pre); - if (!loc) + t = format_location(rr->loc.latitude, + rr->loc.longitude, + rr->loc.altitude, + rr->loc.size, + rr->loc.horiz_pre, + rr->loc.vert_pre); + if (!t) return -ENOMEM; - s = strjoin(k, " ", loc, NULL); + s = strjoin(k, " ", t, NULL); if (!s) return -ENOMEM; - break; - } - - case DNS_TYPE_SSHFP: { - _cleanup_free_ char *x = NULL; - x = hexmem(rr->sshfp.key, rr->sshfp.key_size); - if (!x) + case DNS_TYPE_SSHFP: + t = hexmem(rr->sshfp.key, rr->sshfp.key_size); + if (!t) return -ENOMEM; r = asprintf(&s, "%s %u %u %s", k, rr->sshfp.algorithm, rr->sshfp.fptype, - x); + t); + if (r < 0) + return -ENOMEM; + break; + + case DNS_TYPE_DNSKEY: { + const char *alg; + + alg = dnssec_algorithm_to_string(rr->dnskey.algorithm); + + t = hexmem(rr->dnskey.key, rr->dnskey.key_size); + if (!t) + return -ENOMEM; + + r = asprintf(&s, "%s %u 3 %.*s%.*u %s", + k, + dnskey_to_flags(rr), + alg ? -1 : 0, alg, + alg ? 0 : 1, alg ? 0u : (unsigned) rr->dnskey.algorithm, + t); if (r < 0) return -ENOMEM; break; } - default: { - _cleanup_free_ char *x = NULL; + case DNS_TYPE_RRSIG: { + const char *type, *alg; + + type = dns_type_to_string(rr->rrsig.type_covered); + alg = dnssec_algorithm_to_string(rr->rrsig.algorithm); - x = hexmem(rr->generic.data, rr->generic.size); - if (!x) + t = hexmem(rr->rrsig.signature, rr->rrsig.signature_size); + if (!t) return -ENOMEM; - s = strjoin(k, " ", x, NULL); + /* TYPE?? follows + * http://tools.ietf.org/html/rfc3597#section-5 */ + + r = asprintf(&s, "%s %s%.*u %.*s%.*u %u %u %u %u %u %s %s", + k, + type ?: "TYPE", + type ? 0 : 1, type ? 0u : (unsigned) rr->rrsig.type_covered, + alg ? -1 : 0, alg, + alg ? 0 : 1, alg ? 0u : (unsigned) rr->rrsig.algorithm, + rr->rrsig.labels, + rr->rrsig.original_ttl, + rr->rrsig.expiration, + rr->rrsig.inception, + rr->rrsig.key_tag, + rr->rrsig.signer, + t); + if (r < 0) + return -ENOMEM; + break; + } + + default: + t = hexmem(rr->generic.data, rr->generic.size); + if (!t) + return -ENOMEM; + + s = strjoin(k, " ", t, NULL); if (!s) return -ENOMEM; break; - }} + } *ret = s; return 0; @@ -627,54 +697,3 @@ int dns_class_from_string(const char *s, uint16_t *class) { return 0; } - -static const struct { - uint16_t type; - const char *name; -} dns_types[] = { - { DNS_TYPE_A, "A" }, - { DNS_TYPE_NS, "NS" }, - { DNS_TYPE_CNAME, "CNAME" }, - { DNS_TYPE_SOA, "SOA" }, - { DNS_TYPE_PTR, "PTR" }, - { DNS_TYPE_HINFO, "HINFO" }, - { DNS_TYPE_MX, "MX" }, - { DNS_TYPE_TXT, "TXT" }, - { DNS_TYPE_AAAA, "AAAA" }, - { DNS_TYPE_LOC, "LOC" }, - { DNS_TYPE_SRV, "SRV" }, - { DNS_TYPE_SSHFP, "SSHFP" }, - { DNS_TYPE_SPF, "SPF" }, - { DNS_TYPE_DNAME, "DNAME" }, - { DNS_TYPE_ANY, "ANY" }, - { DNS_TYPE_OPT, "OPT" }, - { DNS_TYPE_TKEY, "TKEY" }, - { DNS_TYPE_TSIG, "TSIG" }, - { DNS_TYPE_IXFR, "IXFR" }, - { DNS_TYPE_AXFR, "AXFR" }, -}; - -const char *dns_type_to_string(uint16_t type) { - unsigned i; - - for (i = 0; i < ELEMENTSOF(dns_types); i++) - if (dns_types[i].type == type) - return dns_types[i].name; - - return NULL; -} - -int dns_type_from_string(const char *s, uint16_t *type) { - unsigned i; - - assert(s); - assert(type); - - for (i = 0; i < ELEMENTSOF(dns_types); i++) - if (strcaseeq(dns_types[i].name, s)) { - *type = dns_types[i].type; - return 0; - } - - return -EINVAL; -}