summaryrefslogtreecommitdiff
path: root/src/resolve
diff options
context:
space:
mode:
Diffstat (limited to 'src/resolve')
-rw-r--r--src/resolve/dns-type.h4
-rw-r--r--src/resolve/resolve-tool.c120
-rw-r--r--src/resolve/resolved-bus.c11
-rw-r--r--src/resolve/resolved-conf.c4
-rw-r--r--src/resolve/resolved-dns-answer.c6
-rw-r--r--src/resolve/resolved-dns-cache.c8
-rw-r--r--src/resolve/resolved-dns-packet.c6
-rw-r--r--src/resolve/resolved-dns-query.c7
-rw-r--r--src/resolve/resolved-dns-rr.c33
-rw-r--r--src/resolve/resolved-dns-rr.h2
-rw-r--r--src/resolve/resolved-dns-server.c8
-rw-r--r--src/resolve/resolved-dns-transaction.c66
-rw-r--r--src/resolve/resolved-dns-transaction.h6
-rw-r--r--src/resolve/resolved-dns-zone.c5
-rw-r--r--src/resolve/resolved-etc-hosts.c2
-rw-r--r--src/resolve/resolved-llmnr.c2
-rw-r--r--src/resolve/resolved-resolv-conf.c4
-rw-r--r--src/resolve/resolved.c2
-rw-r--r--src/resolve/test-dns-packet.c1
-rw-r--r--src/resolve/test-dnssec.c2
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;
}