diff options
author | Lennart Poettering <lennart@poettering.net> | 2015-12-21 16:31:29 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2015-12-26 19:09:10 +0100 |
commit | 7b50eb2efa122200e39646c19a29abab302f7d24 (patch) | |
tree | 32160f39e5bf23474815e1d21d02ce2739557884 /src/resolve | |
parent | 0936416a1cba187dc76903dae73246f4cbddf312 (diff) |
resolved: internalize string buffer of dns_resource_record_to_string()
Let's simplify usage and memory management of DnsResourceRecord's
dns_resource_record_to_string() call: cache the formatted string as
part of the object, and return it on subsequent calls, freeing it when
the DnsResourceRecord itself is freed.
Diffstat (limited to 'src/resolve')
-rw-r--r-- | src/resolve/resolved-dns-answer.c | 8 | ||||
-rw-r--r-- | src/resolve/resolved-dns-cache.c | 11 | ||||
-rw-r--r-- | src/resolve/resolved-dns-rr.c | 74 | ||||
-rw-r--r-- | src/resolve/resolved-dns-rr.h | 3 | ||||
-rw-r--r-- | src/resolve/resolved-dns-transaction.c | 7 | ||||
-rw-r--r-- | src/resolve/resolved-dns-zone.c | 21 | ||||
-rw-r--r-- | src/resolve/test-dnssec.c | 35 |
7 files changed, 69 insertions, 90 deletions
diff --git a/src/resolve/resolved-dns-answer.c b/src/resolve/resolved-dns-answer.c index 7e64ca52b7..4dea4a2d45 100644 --- a/src/resolve/resolved-dns-answer.c +++ b/src/resolve/resolved-dns-answer.c @@ -657,18 +657,18 @@ int dns_answer_reserve_or_clone(DnsAnswer **a, unsigned n_free) { void dns_answer_dump(DnsAnswer *answer, FILE *f) { DnsResourceRecord *rr; DnsAnswerFlags flags; - int ifindex, r; + int ifindex; if (!f) f = stdout; DNS_ANSWER_FOREACH_FULL(rr, ifindex, flags, answer) { - _cleanup_free_ char *t = NULL; + const char *t; fputc('\t', f); - r = dns_resource_record_to_string(rr, &t); - if (r < 0) { + t = dns_resource_record_to_string(rr); + if (!t) { log_oom(); continue; } diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c index e8541d5e14..f9fe2c2e30 100644 --- a/src/resolve/resolved-dns-cache.c +++ b/src/resolve/resolved-dns-cache.c @@ -938,13 +938,13 @@ void dns_cache_dump(DnsCache *cache, FILE *f) { DnsCacheItem *j; LIST_FOREACH(by_key, j, i) { - _cleanup_free_ char *t = NULL; fputc('\t', f); if (j->rr) { - r = dns_resource_record_to_string(j->rr, &t); - if (r < 0) { + const char *t; + t = dns_resource_record_to_string(j->rr); + if (!t) { log_oom(); continue; } @@ -952,13 +952,14 @@ void dns_cache_dump(DnsCache *cache, FILE *f) { fputs(t, f); fputc('\n', f); } else { - r = dns_resource_key_to_string(j->key, &t); + _cleanup_free_ char *z = NULL; + r = dns_resource_key_to_string(j->key, &z); if (r < 0) { log_oom(); continue; } - fputs(t, f); + fputs(z, f); fputs(" -- ", f); fputs(j->type == DNS_CACHE_NODATA ? "NODATA" : "NXDOMAIN", f); fputc('\n', f); diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c index 067fb1cd08..04d442bf03 100644 --- a/src/resolve/resolved-dns-rr.c +++ b/src/resolve/resolved-dns-rr.c @@ -448,6 +448,7 @@ DnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr) { dns_resource_key_unref(rr->key); } + free(rr->to_string); free(rr); return NULL; @@ -763,16 +764,19 @@ static char *format_txt(DnsTxtItem *first) { return s; } -int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) { +const char *dns_resource_record_to_string(DnsResourceRecord *rr) { _cleanup_free_ char *k = NULL, *t = NULL; char *s; int r; assert(rr); + if (rr->to_string) + return rr->to_string; + r = dns_resource_key_to_string(rr->key, &k); if (r < 0) - return r; + return NULL; switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) { @@ -784,7 +788,7 @@ int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) { rr->srv.port, strna(rr->srv.name)); if (r < 0) - return -ENOMEM; + return NULL; break; case DNS_TYPE_PTR: @@ -793,25 +797,25 @@ int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) { case DNS_TYPE_DNAME: s = strjoin(k, " ", rr->ptr.name, NULL); if (!s) - return -ENOMEM; + return NULL; break; case DNS_TYPE_HINFO: s = strjoin(k, " ", rr->hinfo.cpu, " ", rr->hinfo.os, NULL); if (!s) - return -ENOMEM; + return NULL; break; case DNS_TYPE_SPF: /* exactly the same as TXT */ case DNS_TYPE_TXT: t = format_txt(rr->txt.items); if (!t) - return -ENOMEM; + return NULL; s = strjoin(k, " ", t, NULL); if (!s) - return -ENOMEM; + return NULL; break; case DNS_TYPE_A: { @@ -819,22 +823,22 @@ int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) { r = in_addr_to_string(AF_INET, (const union in_addr_union*) &rr->a.in_addr, &x); if (r < 0) - return r; + return NULL; s = strjoin(k, " ", x, NULL); if (!s) - return -ENOMEM; + return NULL; break; } 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; + return NULL; s = strjoin(k, " ", t, NULL); if (!s) - return -ENOMEM; + return NULL; break; case DNS_TYPE_SOA: @@ -848,7 +852,7 @@ int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) { rr->soa.expire, rr->soa.minimum); if (r < 0) - return -ENOMEM; + return NULL; break; case DNS_TYPE_MX: @@ -857,7 +861,7 @@ int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) { rr->mx.priority, rr->mx.exchange); if (r < 0) - return -ENOMEM; + return NULL; break; case DNS_TYPE_LOC: @@ -870,17 +874,17 @@ int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) { rr->loc.horiz_pre, rr->loc.vert_pre); if (!t) - return -ENOMEM; + return NULL; s = strjoin(k, " ", t, NULL); if (!s) - return -ENOMEM; + return NULL; break; case DNS_TYPE_DS: t = hexmem(rr->ds.digest, rr->ds.digest_size); if (!t) - return -ENOMEM; + return NULL; r = asprintf(&s, "%s %u %u %u %s", k, @@ -889,13 +893,13 @@ int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) { rr->ds.digest_type, t); if (r < 0) - return -ENOMEM; + return NULL; break; case DNS_TYPE_SSHFP: t = hexmem(rr->sshfp.fingerprint, rr->sshfp.fingerprint_size); if (!t) - return -ENOMEM; + return NULL; r = asprintf(&s, "%s %u %u %s", k, @@ -903,7 +907,7 @@ int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) { rr->sshfp.fptype, t); if (r < 0) - return -ENOMEM; + return NULL; break; case DNS_TYPE_DNSKEY: { @@ -913,7 +917,7 @@ int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) { t = base64mem(rr->dnskey.key, rr->dnskey.key_size); if (!t) - return -ENOMEM; + return NULL; r = asprintf(&s, "%s %u %u %.*s%.*u %s", k, @@ -923,7 +927,7 @@ int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) { alg ? 0 : 1, alg ? 0u : (unsigned) rr->dnskey.algorithm, t); if (r < 0) - return -ENOMEM; + return NULL; break; } @@ -936,15 +940,15 @@ int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) { t = base64mem(rr->rrsig.signature, rr->rrsig.signature_size); if (!t) - return -ENOMEM; + return NULL; r = format_timestamp_dns(expiration, sizeof(expiration), rr->rrsig.expiration); if (r < 0) - return r; + return NULL; r = format_timestamp_dns(inception, sizeof(inception), rr->rrsig.inception); if (r < 0) - return r; + return NULL; /* TYPE?? follows * http://tools.ietf.org/html/rfc3597#section-5 */ @@ -963,21 +967,21 @@ int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) { rr->rrsig.signer, t); if (r < 0) - return -ENOMEM; + return NULL; break; } case DNS_TYPE_NSEC: t = format_types(rr->nsec.types); if (!t) - return -ENOMEM; + return NULL; r = asprintf(&s, "%s %s %s", k, rr->nsec.next_domain_name, t); if (r < 0) - return -ENOMEM; + return NULL; break; case DNS_TYPE_NSEC3: { @@ -986,16 +990,16 @@ int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) { if (rr->nsec3.salt_size > 0) { salt = hexmem(rr->nsec3.salt, rr->nsec3.salt_size); if (!salt) - return -ENOMEM; + return NULL; } hash = base32hexmem(rr->nsec3.next_hashed_name, rr->nsec3.next_hashed_name_size, false); if (!hash) - return -ENOMEM; + return NULL; t = format_types(rr->nsec3.types); if (!t) - return -ENOMEM; + return NULL; r = asprintf(&s, "%s %"PRIu8" %"PRIu8" %"PRIu16" %s %s %s", k, @@ -1006,7 +1010,7 @@ int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) { hash, t); if (r < 0) - return -ENOMEM; + return NULL; break; } @@ -1014,16 +1018,16 @@ int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret) { default: t = hexmem(rr->generic.data, rr->generic.size); if (!t) - return -ENOMEM; + return NULL; r = asprintf(&s, "%s \\# %zu %s", k, rr->generic.size, t); if (r < 0) - return -ENOMEM; + return NULL; break; } - *ret = s; - return 0; + rr->to_string = s; + return s; } int dns_resource_record_to_wire_format(DnsResourceRecord *rr, bool canonical) { diff --git a/src/resolve/resolved-dns-rr.h b/src/resolve/resolved-dns-rr.h index a35f01ce10..f2997883a8 100644 --- a/src/resolve/resolved-dns-rr.h +++ b/src/resolve/resolved-dns-rr.h @@ -95,6 +95,7 @@ struct DnsTxtItem { struct DnsResourceRecord { unsigned n_ref; DnsResourceKey *key; + char *to_string; uint32_t ttl; bool unparseable:1; bool wire_format_canonical:1; @@ -253,7 +254,7 @@ DnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr); int dns_resource_record_new_reverse(DnsResourceRecord **ret, int family, const union in_addr_union *address, const char *name); int dns_resource_record_new_address(DnsResourceRecord **ret, int family, const union in_addr_union *address, const char *name); int dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecord *b); -int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret); +const char* dns_resource_record_to_string(DnsResourceRecord *rr); DEFINE_TRIVIAL_CLEANUP_FUNC(DnsResourceRecord*, dns_resource_record_unref); int dns_resource_record_to_wire_format(DnsResourceRecord *rr, bool canonical); diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c index 347b1683f9..d2aec13264 100644 --- a/src/resolve/resolved-dns-transaction.c +++ b/src/resolve/resolved-dns-transaction.c @@ -1906,12 +1906,7 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) { if (r < 0) return r; - if (log_get_max_level() >= LOG_DEBUG) { - _cleanup_free_ char *rrs = NULL; - - (void) dns_resource_record_to_string(rr, &rrs); - log_debug("Looking at %s: %s", rrs ? strstrip(rrs) : "???", dnssec_result_to_string(result)); - } + log_debug("Looking at %s: %s", strna(dns_resource_record_to_string(rr)), dnssec_result_to_string(result)); if (result == DNSSEC_VALIDATED) { diff --git a/src/resolve/resolved-dns-zone.c b/src/resolve/resolved-dns-zone.c index 20c8a4da90..f60b0bddc1 100644 --- a/src/resolve/resolved-dns-zone.c +++ b/src/resolve/resolved-dns-zone.c @@ -471,15 +471,12 @@ return_empty: } void dns_zone_item_conflict(DnsZoneItem *i) { - _cleanup_free_ char *pretty = NULL; - assert(i); if (!IN_SET(i->state, DNS_ZONE_ITEM_PROBING, DNS_ZONE_ITEM_VERIFYING, DNS_ZONE_ITEM_ESTABLISHED)) return; - dns_resource_record_to_string(i->rr, &pretty); - log_info("Detected conflict on %s", strna(pretty)); + log_info("Detected conflict on %s", strna(dns_resource_record_to_string(i->rr))); dns_zone_item_probe_stop(i); @@ -492,8 +489,6 @@ void dns_zone_item_conflict(DnsZoneItem *i) { } void dns_zone_item_notify(DnsZoneItem *i) { - _cleanup_free_ char *pretty = NULL; - assert(i); assert(i->probe_transaction); @@ -530,15 +525,13 @@ void dns_zone_item_notify(DnsZoneItem *i) { log_debug("Got a successful probe reply, but peer has lexicographically lower IP address and thus lost."); } - dns_resource_record_to_string(i->rr, &pretty); - log_debug("Record %s successfully probed.", strna(pretty)); + log_debug("Record %s successfully probed.", strna(dns_resource_record_to_string(i->rr))); dns_zone_item_probe_stop(i); i->state = DNS_ZONE_ITEM_ESTABLISHED; } static int dns_zone_item_verify(DnsZoneItem *i) { - _cleanup_free_ char *pretty = NULL; int r; assert(i); @@ -546,8 +539,7 @@ static int dns_zone_item_verify(DnsZoneItem *i) { if (i->state != DNS_ZONE_ITEM_ESTABLISHED) return 0; - dns_resource_record_to_string(i->rr, &pretty); - log_debug("Verifying RR %s", strna(pretty)); + log_debug("Verifying RR %s", strna(dns_resource_record_to_string(i->rr))); i->state = DNS_ZONE_ITEM_VERIFYING; r = dns_zone_item_probe_start(i); @@ -632,7 +624,6 @@ void dns_zone_verify_all(DnsZone *zone) { void dns_zone_dump(DnsZone *zone, FILE *f) { Iterator iterator; DnsZoneItem *i; - int r; if (!zone) return; @@ -644,10 +635,10 @@ void dns_zone_dump(DnsZone *zone, FILE *f) { DnsZoneItem *j; LIST_FOREACH(by_key, j, i) { - _cleanup_free_ char *t = NULL; + const char *t; - r = dns_resource_record_to_string(j->rr, &t); - if (r < 0) { + t = dns_resource_record_to_string(j->rr); + if (!t) { log_oom(); continue; } diff --git a/src/resolve/test-dnssec.c b/src/resolve/test-dnssec.c index 5b4ee220c4..6104d8b4c0 100644 --- a/src/resolve/test-dnssec.c +++ b/src/resolve/test-dnssec.c @@ -56,7 +56,6 @@ static void test_dnssec_verify_rrset2(void) { _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *nsec = NULL, *rrsig = NULL, *dnskey = NULL; _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL; - _cleanup_free_ char *x = NULL, *y = NULL, *z = NULL; DnssecResult result; nsec = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_NSEC, "nasa.gov"); @@ -77,8 +76,7 @@ static void test_dnssec_verify_rrset2(void) { assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_DNSKEY) >= 0); assert_se(bitmap_set(nsec->nsec.types, 65534) >= 0); - assert_se(dns_resource_record_to_string(nsec, &x) >= 0); - log_info("NSEC: %s", x); + log_info("NSEC: %s", strna(dns_resource_record_to_string(nsec))); rrsig = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_RRSIG, "NaSa.GOV."); assert_se(rrsig); @@ -96,8 +94,7 @@ static void test_dnssec_verify_rrset2(void) { rrsig->rrsig.signature = memdup(signature_blob, rrsig->rrsig.signature_size); assert_se(rrsig->rrsig.signature); - assert_se(dns_resource_record_to_string(rrsig, &y) >= 0); - log_info("RRSIG: %s", y); + log_info("RRSIG: %s", strna(dns_resource_record_to_string(rrsig))); dnskey = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNSKEY, "nASA.gOV"); assert_se(dnskey); @@ -109,8 +106,7 @@ static void test_dnssec_verify_rrset2(void) { dnskey->dnskey.key = memdup(dnskey_blob, sizeof(dnskey_blob)); assert_se(dnskey->dnskey.key); - assert_se(dns_resource_record_to_string(dnskey, &z) >= 0); - log_info("DNSKEY: %s", z); + log_info("DNSKEY: %s", strna(dns_resource_record_to_string(dnskey))); log_info("DNSKEY keytag: %u", dnssec_keytag(dnskey)); assert_se(dnssec_key_match_rrsig(nsec->key, rrsig) > 0); @@ -152,7 +148,6 @@ static void test_dnssec_verify_rrset(void) { _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *a = NULL, *rrsig = NULL, *dnskey = NULL; _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL; - _cleanup_free_ char *x = NULL, *y = NULL, *z = NULL; DnssecResult result; a = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "nAsA.gov"); @@ -160,8 +155,7 @@ static void test_dnssec_verify_rrset(void) { a->a.in_addr.s_addr = inet_addr("52.0.14.116"); - assert_se(dns_resource_record_to_string(a, &x) >= 0); - log_info("A: %s", x); + log_info("A: %s", strna(dns_resource_record_to_string(a))); rrsig = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_RRSIG, "NaSa.GOV."); assert_se(rrsig); @@ -179,8 +173,7 @@ static void test_dnssec_verify_rrset(void) { rrsig->rrsig.signature = memdup(signature_blob, rrsig->rrsig.signature_size); assert_se(rrsig->rrsig.signature); - assert_se(dns_resource_record_to_string(rrsig, &y) >= 0); - log_info("RRSIG: %s", y); + log_info("RRSIG: %s", strna(dns_resource_record_to_string(rrsig))); dnskey = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNSKEY, "nASA.gOV"); assert_se(dnskey); @@ -192,8 +185,7 @@ static void test_dnssec_verify_rrset(void) { dnskey->dnskey.key = memdup(dnskey_blob, sizeof(dnskey_blob)); assert_se(dnskey->dnskey.key); - assert_se(dns_resource_record_to_string(dnskey, &z) >= 0); - log_info("DNSKEY: %s", z); + log_info("DNSKEY: %s", strna(dns_resource_record_to_string(dnskey))); log_info("DNSKEY keytag: %u", dnssec_keytag(dnskey)); assert_se(dnssec_key_match_rrsig(a->key, rrsig) > 0); @@ -239,7 +231,6 @@ static void test_dnssec_verify_dns_key(void) { }; _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *dnskey = NULL, *ds1 = NULL, *ds2 = NULL; - _cleanup_free_ char *a = NULL, *b = NULL, *c = NULL; /* The two DS RRs in effect for nasa.gov on 2015-12-01. */ ds1 = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DS, "nasa.gov"); @@ -252,8 +243,7 @@ static void test_dnssec_verify_dns_key(void) { ds1->ds.digest = memdup(ds1_fprint, ds1->ds.digest_size); assert_se(ds1->ds.digest); - assert_se(dns_resource_record_to_string(ds1, &a) >= 0); - log_info("DS1: %s", a); + log_info("DS1: %s", strna(dns_resource_record_to_string(ds1))); ds2 = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DS, "NASA.GOV"); assert_se(ds2); @@ -265,8 +255,7 @@ static void test_dnssec_verify_dns_key(void) { ds2->ds.digest = memdup(ds2_fprint, ds2->ds.digest_size); assert_se(ds2->ds.digest); - assert_se(dns_resource_record_to_string(ds2, &b) >= 0); - log_info("DS2: %s", b); + log_info("DS2: %s", strna(dns_resource_record_to_string(ds2))); dnskey = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNSKEY, "nasa.GOV"); assert_se(dnskey); @@ -278,8 +267,7 @@ static void test_dnssec_verify_dns_key(void) { dnskey->dnskey.key = memdup(dnskey_blob, sizeof(dnskey_blob)); assert_se(dnskey->dnskey.key); - assert_se(dns_resource_record_to_string(dnskey, &c) >= 0); - log_info("DNSKEY: %s", c); + log_info("DNSKEY: %s", strna(dns_resource_record_to_string(dnskey))); log_info("DNSKEY keytag: %u", dnssec_keytag(dnskey)); assert_se(dnssec_verify_dnskey(dnskey, ds1) > 0); @@ -310,8 +298,8 @@ static void test_dnssec_nsec3_hash(void) { static const uint8_t salt[] = { 0xB0, 0x1D, 0xFA, 0xCE }; static const uint8_t next_hashed_name[] = { 0x84, 0x10, 0x26, 0x53, 0xc9, 0xfa, 0x4d, 0x85, 0x6c, 0x97, 0x82, 0xe2, 0x8f, 0xdf, 0x2d, 0x5e, 0x87, 0x69, 0xc4, 0x52 }; _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL; - _cleanup_free_ char *a = NULL, *b = NULL; uint8_t h[DNSSEC_HASH_SIZE_MAX]; + _cleanup_free_ char *b = NULL; int k; /* The NSEC3 RR for eurid.eu on 2015-12-14. */ @@ -328,8 +316,7 @@ static void test_dnssec_nsec3_hash(void) { assert_se(rr->nsec3.next_hashed_name); rr->nsec3.next_hashed_name_size = sizeof(next_hashed_name); - assert_se(dns_resource_record_to_string(rr, &a) >= 0); - log_info("NSEC3: %s", a); + log_info("NSEC3: %s", strna(dns_resource_record_to_string(rr))); k = dnssec_nsec3_hash(rr, "eurid.eu", &h); assert_se(k >= 0); |