diff options
Diffstat (limited to 'src/resolve')
-rw-r--r-- | src/resolve/dns-type.h | 4 | ||||
-rw-r--r-- | src/resolve/resolve-tool.c | 120 | ||||
-rw-r--r-- | src/resolve/resolved-bus.c | 11 | ||||
-rw-r--r-- | src/resolve/resolved-conf.c | 4 | ||||
-rw-r--r-- | src/resolve/resolved-dns-answer.c | 6 | ||||
-rw-r--r-- | src/resolve/resolved-dns-cache.c | 8 | ||||
-rw-r--r-- | src/resolve/resolved-dns-packet.c | 6 | ||||
-rw-r--r-- | src/resolve/resolved-dns-query.c | 7 | ||||
-rw-r--r-- | src/resolve/resolved-dns-rr.c | 33 | ||||
-rw-r--r-- | src/resolve/resolved-dns-rr.h | 2 | ||||
-rw-r--r-- | src/resolve/resolved-dns-server.c | 8 | ||||
-rw-r--r-- | src/resolve/resolved-dns-transaction.c | 66 | ||||
-rw-r--r-- | src/resolve/resolved-dns-transaction.h | 6 | ||||
-rw-r--r-- | src/resolve/resolved-dns-zone.c | 5 | ||||
-rw-r--r-- | src/resolve/resolved-etc-hosts.c | 2 | ||||
-rw-r--r-- | src/resolve/resolved-llmnr.c | 2 | ||||
-rw-r--r-- | src/resolve/resolved-resolv-conf.c | 4 | ||||
-rw-r--r-- | src/resolve/resolved.c | 2 | ||||
-rw-r--r-- | src/resolve/test-dns-packet.c | 1 | ||||
-rw-r--r-- | src/resolve/test-dnssec.c | 2 |
20 files changed, 190 insertions, 109 deletions
diff --git a/src/resolve/dns-type.h b/src/resolve/dns-type.h index db9666b970..7b79d29d7e 100644 --- a/src/resolve/dns-type.h +++ b/src/resolve/dns-type.h @@ -1,3 +1,5 @@ +#pragma once + /*** This file is part of systemd. @@ -17,8 +19,6 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#pragma once - #include "macro.h" /* DNS record types, taken from diff --git a/src/resolve/resolve-tool.c b/src/resolve/resolve-tool.c index a519074278..14ee01c49d 100644 --- a/src/resolve/resolve-tool.c +++ b/src/resolve/resolve-tool.c @@ -17,7 +17,6 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <gcrypt.h> #include <getopt.h> #include <net/if.h> @@ -44,12 +43,19 @@ static uint16_t arg_class = 0; static bool arg_legend = true; static uint64_t arg_flags = 0; +typedef enum ServiceFamily { + SERVICE_FAMILY_TCP, + SERVICE_FAMILY_UDP, + SERVICE_FAMILY_SCTP, + _SERVICE_FAMILY_INVALID = -1, +} ServiceFamily; +static ServiceFamily arg_service_family = SERVICE_FAMILY_TCP; + typedef enum RawType { RAW_NONE, RAW_PAYLOAD, RAW_PACKET, } RawType; - static RawType arg_raw = RAW_NONE; static enum { @@ -57,10 +63,34 @@ static enum { MODE_RESOLVE_RECORD, MODE_RESOLVE_SERVICE, MODE_RESOLVE_OPENPGP, + MODE_RESOLVE_TLSA, MODE_STATISTICS, MODE_RESET_STATISTICS, } arg_mode = MODE_RESOLVE_HOST; +static ServiceFamily service_family_from_string(const char *s) { + if (s == NULL || streq(s, "tcp")) + return SERVICE_FAMILY_TCP; + if (streq(s, "udp")) + return SERVICE_FAMILY_UDP; + if (streq(s, "sctp")) + return SERVICE_FAMILY_SCTP; + return _SERVICE_FAMILY_INVALID; +} + +static const char* service_family_to_string(ServiceFamily service) { + switch(service) { + case SERVICE_FAMILY_TCP: + return "_tcp"; + case SERVICE_FAMILY_UDP: + return "_udp"; + case SERVICE_FAMILY_SCTP: + return "_sctp"; + default: + assert_not_reached("invalid service"); + } +} + static void print_source(uint64_t flags, usec_t rtt) { char rtt_str[FORMAT_TIMESTAMP_MAX]; @@ -832,7 +862,7 @@ static int resolve_openpgp(sd_bus *bus, const char *address) { } domain++; - r = string_hashsum(address, domain - 1 - address, GCRY_MD_SHA224, &hashed); + r = string_hashsum_sha224(address, domain - 1 - address, &hashed); if (r < 0) return log_error_errno(r, "Hashing failed: %m"); @@ -844,6 +874,38 @@ static int resolve_openpgp(sd_bus *bus, const char *address) { arg_type ?: DNS_TYPE_OPENPGPKEY); } +static int resolve_tlsa(sd_bus *bus, const char *address) { + const char *port; + uint16_t port_num = 443; + _cleanup_free_ char *full = NULL; + int r; + + assert(bus); + assert(address); + + port = strrchr(address, ':'); + if (port) { + r = safe_atou16(port + 1, &port_num); + if (r < 0 || port_num == 0) + return log_error_errno(r, "Invalid port \"%s\".", port + 1); + + address = strndupa(address, port - address); + } + + r = asprintf(&full, "_%u.%s.%s", + port_num, + service_family_to_string(arg_service_family), + address); + if (r < 0) + return log_oom(); + + log_debug("Looking up \"%s\".", full); + + return resolve_record(bus, full, + arg_class ?: DNS_CLASS_IN, + arg_type ?: DNS_TYPE_TLSA); +} + static int show_statistics(sd_bus *bus) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; @@ -1031,6 +1093,7 @@ static void help(void) { " --service-address=BOOL Resolve address for services (default: yes)\n" " --service-txt=BOOL Resolve TXT records for services (default: yes)\n" " --openpgp Query OpenPGP public key\n" + " --tlsa Query TLS public key\n" " --cname=BOOL Follow CNAME redirects (default: yes)\n" " --search=BOOL Use search domains for single-label names\n" " (default: yes)\n" @@ -1050,6 +1113,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_SERVICE_ADDRESS, ARG_SERVICE_TXT, ARG_OPENPGP, + ARG_TLSA, ARG_RAW, ARG_SEARCH, ARG_STATISTICS, @@ -1069,6 +1133,7 @@ static int parse_argv(int argc, char *argv[]) { { "service-address", required_argument, NULL, ARG_SERVICE_ADDRESS }, { "service-txt", required_argument, NULL, ARG_SERVICE_TXT }, { "openpgp", no_argument, NULL, ARG_OPENPGP }, + { "tlsa", optional_argument, NULL, ARG_TLSA }, { "raw", optional_argument, NULL, ARG_RAW }, { "search", required_argument, NULL, ARG_SEARCH }, { "statistics", no_argument, NULL, ARG_STATISTICS, }, @@ -1183,6 +1248,15 @@ static int parse_argv(int argc, char *argv[]) { arg_mode = MODE_RESOLVE_OPENPGP; break; + case ARG_TLSA: + arg_mode = MODE_RESOLVE_TLSA; + arg_service_family = service_family_from_string(optarg); + if (arg_service_family < 0) { + log_error("Unknown service family \"%s\".", optarg); + return -EINVAL; + } + break; + case ARG_RAW: if (on_tty()) { log_error("Refusing to write binary data to tty."); @@ -1205,40 +1279,28 @@ static int parse_argv(int argc, char *argv[]) { r = parse_boolean(optarg); if (r < 0) return log_error_errno(r, "Failed to parse --cname= argument."); - if (r == 0) - arg_flags |= SD_RESOLVED_NO_CNAME; - else - arg_flags &= ~SD_RESOLVED_NO_CNAME; + SET_FLAG(arg_flags, SD_RESOLVED_NO_CNAME, r == 0); break; case ARG_SERVICE_ADDRESS: r = parse_boolean(optarg); if (r < 0) return log_error_errno(r, "Failed to parse --service-address= argument."); - if (r == 0) - arg_flags |= SD_RESOLVED_NO_ADDRESS; - else - arg_flags &= ~SD_RESOLVED_NO_ADDRESS; + SET_FLAG(arg_flags, SD_RESOLVED_NO_ADDRESS, r == 0); break; case ARG_SERVICE_TXT: r = parse_boolean(optarg); if (r < 0) return log_error_errno(r, "Failed to parse --service-txt= argument."); - if (r == 0) - arg_flags |= SD_RESOLVED_NO_TXT; - else - arg_flags &= ~SD_RESOLVED_NO_TXT; + SET_FLAG(arg_flags, SD_RESOLVED_NO_TXT, r == 0); break; case ARG_SEARCH: r = parse_boolean(optarg); if (r < 0) return log_error_errno(r, "Failed to parse --search argument."); - if (r == 0) - arg_flags |= SD_RESOLVED_NO_SEARCH; - else - arg_flags &= ~SD_RESOLVED_NO_SEARCH; + SET_FLAG(arg_flags, SD_RESOLVED_NO_SEARCH, r == 0); break; case ARG_STATISTICS: @@ -1261,7 +1323,7 @@ static int parse_argv(int argc, char *argv[]) { return -EINVAL; } - if (arg_type != 0 && arg_mode != MODE_RESOLVE_RECORD) { + if (arg_type != 0 && arg_mode == MODE_RESOLVE_SERVICE) { log_error("--service and --type= may not be combined."); return -EINVAL; } @@ -1378,6 +1440,24 @@ int main(int argc, char **argv) { } break; + case MODE_RESOLVE_TLSA: + if (argc < optind + 1) { + log_error("Domain name required."); + r = -EINVAL; + goto finish; + + } + + r = 0; + while (optind < argc) { + int k; + + k = resolve_tlsa(bus, argv[optind++]); + if (k < 0) + r = k; + } + break; + case MODE_STATISTICS: if (argc > optind) { log_error("Too many arguments."); diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index a138be2421..16cae8c1e5 100644 --- a/src/resolve/resolved-bus.c +++ b/src/resolve/resolved-bus.c @@ -188,7 +188,7 @@ static void bus_method_resolve_hostname_complete(DnsQuery *q) { if (!canonical) canonical = dns_resource_record_ref(rr); - added ++; + added++; } if (added <= 0) { @@ -418,7 +418,7 @@ static void bus_method_resolve_address_complete(DnsQuery *q) { if (r < 0) goto finish; - added ++; + added++; } if (added <= 0) { @@ -587,7 +587,7 @@ static void bus_method_resolve_record_complete(DnsQuery *q) { if (r < 0) goto finish; - added ++; + added++; } if (added <= 0) { @@ -1094,9 +1094,9 @@ static void bus_method_resolve_service_complete(DnsQuery *q) { } if ((q->flags & SD_RESOLVED_NO_ADDRESS) == 0) { - q->block_all_complete ++; + q->block_all_complete++; r = resolve_service_hostname(q, rr, ifindex); - q->block_all_complete --; + q->block_all_complete--; if (r < 0) goto finish; @@ -1137,7 +1137,6 @@ finish: static int bus_method_resolve_service(sd_bus_message *message, void *userdata, sd_bus_error *error) { _cleanup_(dns_question_unrefp) DnsQuestion *question_idna = NULL, *question_utf8 = NULL; const char *name, *type, *domain; - _cleanup_free_ char *n = NULL; Manager *m = userdata; int family, ifindex; uint64_t flags; diff --git a/src/resolve/resolved-conf.c b/src/resolve/resolved-conf.c index bb93fbfda2..990dc03b60 100644 --- a/src/resolve/resolved-conf.c +++ b/src/resolve/resolved-conf.c @@ -59,7 +59,7 @@ int manager_parse_dns_server_string_and_warn(Manager *m, DnsServerType type, con assert(m); assert(string); - for(;;) { + for (;;) { _cleanup_free_ char *word = NULL; r = extract_first_word(&string, &word, NULL, 0); @@ -114,7 +114,7 @@ int manager_parse_search_domains_and_warn(Manager *m, const char *string) { assert(m); assert(string); - for(;;) { + for (;;) { _cleanup_free_ char *word = NULL; r = extract_first_word(&string, &word, NULL, EXTRACT_QUOTES); diff --git a/src/resolve/resolved-dns-answer.c b/src/resolve/resolved-dns-answer.c index c08f7a7edd..0dadf8b1dd 100644 --- a/src/resolve/resolved-dns-answer.c +++ b/src/resolve/resolved-dns-answer.c @@ -538,7 +538,7 @@ int dns_answer_remove_by_key(DnsAnswer **a, const DnsResourceKey *key) { dns_resource_record_unref((*a)->items[i].rr); memmove((*a)->items + i, (*a)->items + i + 1, sizeof(DnsAnswerItem) * ((*a)->n_rrs - i - 1)); - (*a)->n_rrs --; + (*a)->n_rrs--; continue; } else @@ -624,7 +624,7 @@ int dns_answer_remove_by_rr(DnsAnswer **a, DnsResourceRecord *rm) { dns_resource_record_unref((*a)->items[i].rr); memmove((*a)->items + i, (*a)->items + i + 1, sizeof(DnsAnswerItem) * ((*a)->n_rrs - i - 1)); - (*a)->n_rrs --; + (*a)->n_rrs--; continue; } else @@ -757,7 +757,7 @@ int dns_answer_reserve_or_clone(DnsAnswer **a, unsigned n_free) { assert(a); /* Tries to extend the DnsAnswer object. And if that's not - * possibly, since we are not the sole owner, then allocate a + * possible, since we are not the sole owner, then allocate a * new, appropriately sized one. Either way, after this call * the object will only have a single reference, and has room * for at least the specified number of RRs. */ diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c index 4b7672fbbf..77c42d7aad 100644 --- a/src/resolve/resolved-dns-cache.c +++ b/src/resolve/resolved-dns-cache.c @@ -402,7 +402,7 @@ static int dns_cache_put_positive( k = dns_cache_remove_by_rr(c, rr); log_debug("%s: %s", k > 0 ? "Removed zero TTL entry from cache" : "Not caching zero TTL cache entry", - dns_resource_key_to_string(i->key, key_str, sizeof key_str)); + dns_resource_key_to_string(rr->key, key_str, sizeof key_str)); return 0; } @@ -497,7 +497,7 @@ static int dns_cache_put_negative( if (nsec_ttl <= 0 || soa->soa.minimum <= 0 || soa->ttl <= 0) { log_debug("Not caching negative entry with zero SOA/NSEC/NSEC3 TTL: %s", - dns_resource_key_to_string(i->key, key_str, sizeof key_str)); + dns_resource_key_to_string(key, key_str, sizeof key_str)); return 0; } @@ -640,7 +640,7 @@ int dns_cache_put( cache_keys = dns_answer_size(answer); if (key) - cache_keys ++; + cache_keys++; /* Make some space for our new entries */ dns_cache_make_space(c, cache_keys); @@ -987,7 +987,7 @@ int dns_cache_export_shared_to_packet(DnsCache *cache, DnsPacket *p) { if (r < 0) return r; - ancount ++; + ancount++; } } diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index 2e41dae656..b7907bb511 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -38,8 +38,8 @@ static void rewind_dns_packet(DnsPacketRewinder *rewinder) { dns_packet_rewind(rewinder->packet, rewinder->saved_rindex); } -#define INIT_REWINDER(rewinder, p) do { rewinder.packet = p; rewinder.saved_rindex = p->rindex; } while(0) -#define CANCEL_REWINDER(rewinder) do { rewinder.packet = NULL; } while(0) +#define INIT_REWINDER(rewinder, p) do { rewinder.packet = p; rewinder.saved_rindex = p->rindex; } while (0) +#define CANCEL_REWINDER(rewinder) do { rewinder.packet = NULL; } while (0) int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) { DnsPacket *p; @@ -1469,7 +1469,7 @@ static int dns_packet_read_type_window(DnsPacket *p, Bitmap **types, size_t *sta return r; } - bit ++; + bit++; bitmask >>= 1; } } diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c index a7496aa586..706f8c14ed 100644 --- a/src/resolve/resolved-dns-query.c +++ b/src/resolve/resolved-dns-query.c @@ -62,6 +62,7 @@ static void dns_query_candidate_stop(DnsQueryCandidate *c) { while ((t = set_steal_first(c->transactions))) { set_remove(t->notify_query_candidates, c); + set_remove(t->notify_query_candidates_done, c); dns_transaction_gc(t); } } @@ -139,6 +140,10 @@ static int dns_query_candidate_add_transaction(DnsQueryCandidate *c, DnsResource if (r < 0) goto gc; + r = set_ensure_allocated(&t->notify_query_candidates_done, NULL); + if (r < 0) + goto gc; + r = set_put(t->notify_query_candidates, c); if (r < 0) goto gc; @@ -927,7 +932,7 @@ static int dns_query_cname_redirect(DnsQuery *q, const DnsResourceRecord *cname) assert(q); - q->n_cname_redirects ++; + q->n_cname_redirects++; if (q->n_cname_redirects > CNAME_MAX) return -ELOOP; diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c index d0a86ef206..6a29a93a26 100644 --- a/src/resolve/resolved-dns-rr.c +++ b/src/resolve/resolved-dns-rr.c @@ -1116,40 +1116,30 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) { case DNS_TYPE_TLSA: { const char *cert_usage, *selector, *matching_type; - char *ss; - int n; cert_usage = tlsa_cert_usage_to_string(rr->tlsa.cert_usage); selector = tlsa_selector_to_string(rr->tlsa.selector); matching_type = tlsa_matching_type_to_string(rr->tlsa.matching_type); - r = asprintf(&s, "%s %u %u %u %n", - k, - rr->tlsa.cert_usage, - rr->tlsa.selector, - rr->tlsa.matching_type, - &n); - if (r < 0) - return NULL; - - r = base64_append(&s, n, - rr->tlsa.data, rr->tlsa.data_size, - 8, columns()); - if (r < 0) + t = hexmem(rr->sshfp.fingerprint, rr->sshfp.fingerprint_size); + if (!t) return NULL; - r = asprintf(&ss, "%s\n" + r = asprintf(&s, + "%s %u %u %u %s\n" " -- Cert. usage: %s\n" " -- Selector: %s\n" " -- Matching type: %s", - s, + k, + rr->tlsa.cert_usage, + rr->tlsa.selector, + rr->tlsa.matching_type, + t, cert_usage, selector, matching_type); if (r < 0) return NULL; - free(s); - s = ss; break; } @@ -1228,13 +1218,16 @@ ssize_t dns_resource_record_payload(DnsResourceRecord *rr, void **out) { 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: return -EINVAL; + case DNS_TYPE_SSHFP: + *out = rr->sshfp.fingerprint; + return rr->sshfp.fingerprint_size; + case DNS_TYPE_TLSA: *out = rr->tlsa.data; return rr->tlsa.data_size; diff --git a/src/resolve/resolved-dns-rr.h b/src/resolve/resolved-dns-rr.h index 646e34598d..020a2abd77 100644 --- a/src/resolve/resolved-dns-rr.h +++ b/src/resolve/resolved-dns-rr.h @@ -82,7 +82,7 @@ enum { struct DnsResourceKey { unsigned n_ref; /* (unsigned -1) for const keys, see below */ uint16_t class, type; - char *_name; /* don't access directy, use dns_resource_key_name()! */ + char *_name; /* don't access directly, use dns_resource_key_name()! */ }; /* Creates a temporary resource key. This is only useful to quickly diff --git a/src/resolve/resolved-dns-server.c b/src/resolve/resolved-dns-server.c index 27342a0e04..49d488cec5 100644 --- a/src/resolve/resolved-dns-server.c +++ b/src/resolve/resolved-dns-server.c @@ -120,7 +120,7 @@ DnsServer* dns_server_ref(DnsServer *s) { return NULL; assert(s->n_ref > 0); - s->n_ref ++; + s->n_ref++; return s; } @@ -130,7 +130,7 @@ DnsServer* dns_server_unref(DnsServer *s) { return NULL; assert(s->n_ref > 0); - s->n_ref --; + s->n_ref--; if (s->n_ref > 0) return NULL; @@ -290,9 +290,9 @@ void dns_server_packet_lost(DnsServer *s, int protocol, DnsServerFeatureLevel le if (s->possible_feature_level == level) { if (protocol == IPPROTO_UDP) - s->n_failed_udp ++; + s->n_failed_udp++; else if (protocol == IPPROTO_TCP) - s->n_failed_tcp ++; + s->n_failed_tcp++; } if (s->resend_timeout > usec) diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c index 3443f71976..a5129c201e 100644 --- a/src/resolve/resolved-dns-transaction.c +++ b/src/resolve/resolved-dns-transaction.c @@ -52,6 +52,7 @@ static void dns_transaction_flush_dnssec_transactions(DnsTransaction *t) { while ((z = set_steal_first(t->dnssec_transactions))) { set_remove(z->notify_transactions, t); + set_remove(z->notify_transactions_done, t); dns_transaction_gc(z); } } @@ -100,14 +101,26 @@ DnsTransaction* dns_transaction_free(DnsTransaction *t) { set_remove(c->transactions, t); set_free(t->notify_query_candidates); + while ((c = set_steal_first(t->notify_query_candidates_done))) + set_remove(c->transactions, t); + set_free(t->notify_query_candidates_done); + while ((i = set_steal_first(t->notify_zone_items))) i->probe_transaction = NULL; set_free(t->notify_zone_items); + while ((i = set_steal_first(t->notify_zone_items_done))) + i->probe_transaction = NULL; + set_free(t->notify_zone_items_done); + while ((z = set_steal_first(t->notify_transactions))) set_remove(z->dnssec_transactions, t); set_free(t->notify_transactions); + while ((z = set_steal_first(t->notify_transactions_done))) + set_remove(z->dnssec_transactions, t); + set_free(t->notify_transactions_done); + dns_transaction_flush_dnssec_transactions(t); set_free(t->dnssec_transactions); @@ -127,8 +140,11 @@ bool dns_transaction_gc(DnsTransaction *t) { return true; if (set_isempty(t->notify_query_candidates) && + set_isempty(t->notify_query_candidates_done) && set_isempty(t->notify_zone_items) && - set_isempty(t->notify_transactions)) { + set_isempty(t->notify_zone_items_done) && + set_isempty(t->notify_transactions) && + set_isempty(t->notify_transactions_done)) { dns_transaction_free(t); return false; } @@ -209,7 +225,7 @@ int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsResourceKey *key) LIST_PREPEND(transactions_by_scope, s->transactions, t); t->scope = s; - s->manager->n_transactions_total ++; + s->manager->n_transactions_total++; if (ret) *ret = t; @@ -266,6 +282,7 @@ static void dns_transaction_tentative(DnsTransaction *t, DnsPacket *p) { log_debug("We have the lexicographically larger IP address and thus lost in the conflict."); t->block_gc++; + while ((z = set_first(t->notify_zone_items))) { /* First, make sure the zone item drops the reference * to us */ @@ -284,7 +301,6 @@ void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) { DnsQueryCandidate *c; DnsZoneItem *z; DnsTransaction *d; - Iterator i; const char *st; char key_str[DNS_RESOURCE_KEY_STRING_MAX]; @@ -333,39 +349,17 @@ void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) { * transaction isn't freed while we are still looking at it */ t->block_gc++; - SET_FOREACH(c, t->notify_query_candidates, i) + SET_FOREACH_MOVE(c, t->notify_query_candidates_done, t->notify_query_candidates) dns_query_candidate_notify(c); - SET_FOREACH(z, t->notify_zone_items, i) - dns_zone_item_notify(z); + SWAP_TWO(t->notify_query_candidates, t->notify_query_candidates_done); - if (!set_isempty(t->notify_transactions)) { - DnsTransaction **nt; - unsigned j, n = 0; - - /* We need to be careful when notifying other - * transactions, as that might destroy other - * transactions in our list. Hence, in order to be - * able to safely iterate through the list of - * transactions, take a GC lock on all of them - * first. Then, in a second loop, notify them, but - * first unlock that specific transaction. */ - - nt = newa(DnsTransaction*, set_size(t->notify_transactions)); - SET_FOREACH(d, t->notify_transactions, i) { - nt[n++] = d; - d->block_gc++; - } - - assert(n == set_size(t->notify_transactions)); + SET_FOREACH_MOVE(z, t->notify_zone_items_done, t->notify_zone_items) + dns_zone_item_notify(z); + SWAP_TWO(t->notify_zone_items, t->notify_zone_items_done); - for (j = 0; j < n; j++) { - if (set_contains(t->notify_transactions, nt[j])) - dns_transaction_notify(nt[j], t); - - nt[j]->block_gc--; - dns_transaction_gc(nt[j]); - } - } + SET_FOREACH_MOVE(d, t->notify_transactions_done, t->notify_transactions) + dns_transaction_notify(d, t); + SWAP_TWO(t->notify_transactions, t->notify_transactions_done); t->block_gc--; dns_transaction_gc(t); @@ -1375,7 +1369,7 @@ static int dns_transaction_make_packet_mdns(DnsTransaction *t) { other->state = DNS_TRANSACTION_PENDING; other->next_attempt_after = ts; - qdcount ++; + qdcount++; if (dns_key_is_shared(other->key)) add_known_answers = true; @@ -1626,6 +1620,10 @@ static int dns_transaction_add_dnssec_transaction(DnsTransaction *t, DnsResource if (r < 0) goto gc; + r = set_ensure_allocated(&aux->notify_transactions_done, NULL); + if (r < 0) + goto gc; + r = set_put(t->dnssec_transactions, aux); if (r < 0) goto gc; diff --git a/src/resolve/resolved-dns-transaction.h b/src/resolve/resolved-dns-transaction.h index 491c62d772..eaece91533 100644 --- a/src/resolve/resolved-dns-transaction.h +++ b/src/resolve/resolved-dns-transaction.h @@ -118,17 +118,17 @@ struct DnsTransaction { /* Query candidates this transaction is referenced by and that * shall be notified about this specific transaction * completing. */ - Set *notify_query_candidates; + Set *notify_query_candidates, *notify_query_candidates_done; /* Zone items this transaction is referenced by and that shall * be notified about completion. */ - Set *notify_zone_items; + Set *notify_zone_items, *notify_zone_items_done; /* Other transactions that this transactions is referenced by * and that shall be notified about completion. This is used * when transactions want to validate their RRsets, but need * another DNSKEY or DS RR to do so. */ - Set *notify_transactions; + Set *notify_transactions, *notify_transactions_done; /* The opposite direction: the transactions this transaction * created in order to request DNSKEY or DS RRs. */ diff --git a/src/resolve/resolved-dns-zone.c b/src/resolve/resolved-dns-zone.c index 03813da6a2..850eed8cb8 100644 --- a/src/resolve/resolved-dns-zone.c +++ b/src/resolve/resolved-dns-zone.c @@ -38,6 +38,7 @@ void dns_zone_item_probe_stop(DnsZoneItem *i) { i->probe_transaction = NULL; set_remove(t->notify_zone_items, i); + set_remove(t->notify_zone_items_done, i); dns_transaction_gc(t); } @@ -186,6 +187,10 @@ static int dns_zone_item_probe_start(DnsZoneItem *i) { if (r < 0) goto gc; + r = set_ensure_allocated(&t->notify_zone_items_done, NULL); + if (r < 0) + goto gc; + r = set_put(t->notify_zone_items, i); if (r < 0) goto gc; diff --git a/src/resolve/resolved-etc-hosts.c b/src/resolve/resolved-etc-hosts.c index 6ccbdca20e..40d650949d 100644 --- a/src/resolve/resolved-etc-hosts.c +++ b/src/resolve/resolved-etc-hosts.c @@ -301,7 +301,7 @@ int manager_etc_hosts_read(Manager *m) { FOREACH_LINE(line, f, return log_error_errno(errno, "Failed to read /etc/hosts: %m")) { char *l; - nr ++; + nr++; l = strstrip(line); if (isempty(l)) diff --git a/src/resolve/resolved-llmnr.c b/src/resolve/resolved-llmnr.c index ef12abfbb5..8b1d71a3eb 100644 --- a/src/resolve/resolved-llmnr.c +++ b/src/resolve/resolved-llmnr.c @@ -286,7 +286,7 @@ static int on_llmnr_stream_packet(DnsStream *s) { scope = manager_find_scope(s->manager, s->read_packet); if (!scope) { - log_warning("Got LLMNR TCP packet on unknown scope. Ignroing."); + log_warning("Got LLMNR TCP packet on unknown scope. Ignoring."); return 0; } diff --git a/src/resolve/resolved-resolv-conf.c b/src/resolve/resolved-resolv-conf.c index 065427b690..ff03acc772 100644 --- a/src/resolve/resolved-resolv-conf.c +++ b/src/resolve/resolved-resolv-conf.c @@ -158,7 +158,7 @@ static void write_resolv_conf_server(DnsServer *s, FILE *f, unsigned *count) { if (*count == MAXNS) fputs("# Too many DNS servers configured, the following entries may be ignored.\n", f); - (*count) ++; + (*count)++; fprintf(f, "nameserver %s\n", s->server_string); } @@ -184,7 +184,7 @@ static void write_resolv_conf_search( } (*length) += strlen(domain); - (*count) ++; + (*count)++; fputc(' ', f); fputs(domain, f); diff --git a/src/resolve/resolved.c b/src/resolve/resolved.c index c7e2ab14d6..161ea03412 100644 --- a/src/resolve/resolved.c +++ b/src/resolve/resolved.c @@ -48,7 +48,7 @@ int main(int argc, char *argv[]) { umask(0022); - r = mac_selinux_init(NULL); + r = mac_selinux_init(); if (r < 0) { log_error_errno(r, "SELinux setup failed: %m"); goto finish; diff --git a/src/resolve/test-dns-packet.c b/src/resolve/test-dns-packet.c index 1abbd3fa2e..c232a69ce1 100644 --- a/src/resolve/test-dns-packet.c +++ b/src/resolve/test-dns-packet.c @@ -89,7 +89,6 @@ static void test_packet_from_file(const char* filename, bool canonical) { int main(int argc, char **argv) { int i, N; _cleanup_globfree_ glob_t g = {}; - _cleanup_strv_free_ char **globs = NULL; char **fnames; log_parse_environment(); diff --git a/src/resolve/test-dnssec.c b/src/resolve/test-dnssec.c index a093d86a91..c9b5ffa62b 100644 --- a/src/resolve/test-dnssec.c +++ b/src/resolve/test-dnssec.c @@ -327,10 +327,12 @@ static void test_dnssec_nsec3_hash(void) { int main(int argc, char*argv[]) { test_dnssec_canonicalize(); +#ifdef HAVE_GCRYPT test_dnssec_verify_dns_key(); test_dnssec_verify_rrset(); test_dnssec_verify_rrset2(); test_dnssec_nsec3_hash(); +#endif return 0; } |