summaryrefslogtreecommitdiff
path: root/src/resolve
diff options
context:
space:
mode:
Diffstat (limited to 'src/resolve')
-rw-r--r--src/resolve/resolved-bus.c6
-rw-r--r--src/resolve/resolved-conf.c35
-rw-r--r--src/resolve/resolved-dns-answer.c25
-rw-r--r--src/resolve/resolved-dns-answer.h1
-rw-r--r--src/resolve/resolved-dns-cache.c120
-rw-r--r--src/resolve/resolved-dns-cache.h8
-rw-r--r--src/resolve/resolved-dns-packet.c10
-rw-r--r--src/resolve/resolved-dns-packet.h12
-rw-r--r--src/resolve/resolved-dns-query.c8
-rw-r--r--src/resolve/resolved-dns-query.h5
-rw-r--r--src/resolve/resolved-dns-question.c11
-rw-r--r--src/resolve/resolved-dns-question.h2
-rw-r--r--src/resolve/resolved-dns-rr.c34
-rw-r--r--src/resolve/resolved-dns-rr.h4
-rw-r--r--src/resolve/resolved-dns-scope.c20
-rw-r--r--src/resolve/resolved-dns-scope.h4
-rw-r--r--src/resolve/resolved-dns-server.c13
-rw-r--r--src/resolve/resolved-dns-stream.c3
-rw-r--r--src/resolve/resolved-dns-transaction.c26
-rw-r--r--src/resolve/resolved-dns-transaction.h4
-rw-r--r--src/resolve/resolved-dns-zone.c259
-rw-r--r--src/resolve/resolved-dns-zone.h6
-rw-r--r--src/resolve/resolved-link.c9
-rw-r--r--src/resolve/resolved-llmnr.c5
-rw-r--r--src/resolve/resolved-manager.c27
-rw-r--r--src/resolve/resolved-manager.h5
-rw-r--r--src/resolve/resolved.c11
27 files changed, 388 insertions, 285 deletions
diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c
index 12c17003e9..f0a3b607d4 100644
--- a/src/resolve/resolved-bus.c
+++ b/src/resolve/resolved-bus.c
@@ -19,9 +19,9 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include "alloc-util.h"
#include "bus-common-errors.h"
#include "bus-util.h"
-
#include "dns-domain.h"
#include "resolved-bus.h"
#include "resolved-def.h"
@@ -191,7 +191,7 @@ static void bus_method_resolve_hostname_complete(DnsQuery *q) {
/* This has a cname? Then update the query with the
* new cname. */
- r = dns_query_cname_redirect(q, cname->cname.name);
+ r = dns_query_cname_redirect(q, cname);
if (r < 0) {
if (r == -ELOOP)
r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop on '%s'", q->request_hostname);
@@ -220,8 +220,6 @@ static void bus_method_resolve_hostname_complete(DnsQuery *q) {
added++;
}
- // what about the cache?
-
/* If we didn't find anything, then let's restart the
* query, this time with the cname */
if (added <= 0) {
diff --git a/src/resolve/resolved-conf.c b/src/resolve/resolved-conf.c
index 7af63b0a82..9207719551 100644
--- a/src/resolve/resolved-conf.c
+++ b/src/resolve/resolved-conf.c
@@ -19,13 +19,15 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include "alloc-util.h"
#include "conf-parser.h"
-
+#include "def.h"
+#include "extract-word.h"
+#include "parse-util.h"
#include "resolved-conf.h"
+#include "string-util.h"
int manager_parse_dns_server(Manager *m, DnsServerType type, const char *string) {
- const char *word, *state;
- size_t length;
DnsServer *first;
int r;
@@ -34,19 +36,22 @@ int manager_parse_dns_server(Manager *m, DnsServerType type, const char *string)
first = type == DNS_SERVER_FALLBACK ? m->fallback_dns_servers : m->dns_servers;
- FOREACH_WORD_QUOTED(word, length, string, state) {
- char buffer[length+1];
- int family;
+ for(;;) {
+ _cleanup_free_ char *word = NULL;
union in_addr_union addr;
bool found = false;
DnsServer *s;
+ int family;
- memcpy(buffer, word, length);
- buffer[length] = 0;
+ r = extract_first_word(&string, &word, NULL, 0);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse resolved dns server syntax \"%s\": %m", string);
+ if (r == 0)
+ break;
- r = in_addr_from_string_auto(buffer, &family, &addr);
+ r = in_addr_from_string_auto(word, &family, &addr);
if (r < 0) {
- log_warning("Ignoring invalid DNS address '%s'", buffer);
+ log_warning("Ignoring invalid DNS address '%s'", word);
continue;
}
@@ -92,10 +97,10 @@ int config_parse_dnsv(
/* Empty assignment means clear the list */
manager_flush_dns_servers(m, ltype);
else {
- /* Otherwise add to the list */
+ /* Otherwise, add to the list */
r = manager_parse_dns_server(m, ltype, rvalue);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to parse DNS server string '%s'. Ignoring.", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse DNS server string '%s'. Ignoring.", rvalue);
return 0;
}
}
@@ -131,7 +136,7 @@ int config_parse_support(
if (support < 0) {
r = parse_boolean(rvalue);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to parse support level '%s'. Ignoring.", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse support level '%s'. Ignoring.", rvalue);
return 0;
}
@@ -145,8 +150,8 @@ int config_parse_support(
int manager_parse_config_file(Manager *m) {
assert(m);
- return config_parse_many("/etc/systemd/resolved.conf",
- CONF_DIRS_NULSTR("systemd/resolved.conf"),
+ return config_parse_many(PKGSYSCONFDIR "/resolved.conf",
+ CONF_PATHS_NULSTR("systemd/resolved.conf.d"),
"Resolve\0",
config_item_perf_lookup, resolved_gperf_lookup,
false, m);
diff --git a/src/resolve/resolved-dns-answer.c b/src/resolve/resolved-dns-answer.c
index 13ad4ca6bd..3cf9c68074 100644
--- a/src/resolve/resolved-dns-answer.c
+++ b/src/resolve/resolved-dns-answer.c
@@ -19,8 +19,10 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "resolved-dns-answer.h"
+#include "alloc-util.h"
#include "dns-domain.h"
+#include "resolved-dns-answer.h"
+#include "string-util.h"
DnsAnswer *dns_answer_new(unsigned n) {
DnsAnswer *a;
@@ -149,6 +151,19 @@ int dns_answer_contains(DnsAnswer *a, DnsResourceKey *key) {
return 0;
}
+int dns_answer_match_soa(DnsResourceKey *key, DnsResourceKey *soa) {
+ if (soa->class != DNS_CLASS_IN)
+ return 0;
+
+ if (soa->type != DNS_TYPE_SOA)
+ return 0;
+
+ if (!dns_name_endswith(DNS_RESOURCE_KEY_NAME(key), DNS_RESOURCE_KEY_NAME(soa)))
+ return 0;
+
+ return 1;
+}
+
int dns_answer_find_soa(DnsAnswer *a, DnsResourceKey *key, DnsResourceRecord **ret) {
unsigned i;
@@ -164,13 +179,7 @@ int dns_answer_find_soa(DnsAnswer *a, DnsResourceKey *key, DnsResourceRecord **r
for (i = 0; i < a->n_rrs; i++) {
- if (a->items[i].rr->key->class != DNS_CLASS_IN)
- continue;
-
- if (a->items[i].rr->key->type != DNS_TYPE_SOA)
- continue;
-
- if (dns_name_endswith(DNS_RESOURCE_KEY_NAME(key), DNS_RESOURCE_KEY_NAME(a->items[i].rr->key))) {
+ if (dns_answer_match_soa(key, a->items[i].rr->key)) {
*ret = a->items[i].rr;
return 1;
}
diff --git a/src/resolve/resolved-dns-answer.h b/src/resolve/resolved-dns-answer.h
index 0757dd60d0..044d73b19c 100644
--- a/src/resolve/resolved-dns-answer.h
+++ b/src/resolve/resolved-dns-answer.h
@@ -49,6 +49,7 @@ DnsAnswer *dns_answer_unref(DnsAnswer *a);
int dns_answer_add(DnsAnswer *a, DnsResourceRecord *rr, int ifindex);
int dns_answer_add_soa(DnsAnswer *a, const char *name, uint32_t ttl);
int dns_answer_contains(DnsAnswer *a, DnsResourceKey *key);
+int dns_answer_match_soa(DnsResourceKey *key, DnsResourceKey *soa);
int dns_answer_find_soa(DnsAnswer *a, DnsResourceKey *key, DnsResourceRecord **ret);
DnsAnswer *dns_answer_merge(DnsAnswer *a, DnsAnswer *b);
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
index cbbbed8c8a..04f64022e0 100644
--- a/src/resolve/resolved-dns-cache.c
+++ b/src/resolve/resolved-dns-cache.c
@@ -19,6 +19,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include "alloc-util.h"
#include "resolved-dns-cache.h"
#include "resolved-dns-packet.h"
@@ -277,13 +278,14 @@ static int dns_cache_put_positive(
/* New TTL is 0? Delete the entry... */
if (rr->ttl <= 0) {
- if (dns_cache_remove(c, rr->key)) {
- r = dns_resource_key_to_string(rr->key, &key_str);
- if (r < 0)
- return r;
+ r = dns_resource_key_to_string(rr->key, &key_str);
+ if (r < 0)
+ return r;
+ if (dns_cache_remove(c, rr->key))
log_debug("Removed zero TTL entry from cache: %s", key_str);
- }
+ else
+ log_debug("Not caching zero TTL cache entry: %s", key_str);
return 0;
}
@@ -361,7 +363,7 @@ static int dns_cache_put_negative(
if (r < 0)
return r;
- log_debug("Ignored negative cache entry with zero SOA TTL: %s", key_str);
+ log_debug("Not caching negative entry with zero SOA TTL: %s", key_str);
return 0;
}
@@ -402,7 +404,7 @@ static int dns_cache_put_negative(
int dns_cache_put(
DnsCache *c,
- DnsQuestion *q,
+ DnsResourceKey *key,
int rcode,
DnsAnswer *answer,
unsigned max_rrs,
@@ -410,16 +412,16 @@ int dns_cache_put(
int owner_family,
const union in_addr_union *owner_address) {
+ DnsResourceRecord *soa = NULL;
unsigned cache_keys, i;
int r;
assert(c);
- if (q) {
- /* First, if we were passed a question, delete all matching old RRs,
+ if (key) {
+ /* First, if we were passed a key, delete all matching old RRs,
* so that we only keep complete by_key in place. */
- for (i = 0; i < q->n_keys; i++)
- dns_cache_remove(c, q->keys[i]);
+ dns_cache_remove(c, key);
}
if (!answer)
@@ -437,8 +439,8 @@ int dns_cache_put(
cache_keys = answer->n_rrs;
- if (q)
- cache_keys += q->n_keys;
+ if (key)
+ cache_keys ++;
/* Make some space for our new entries */
dns_cache_make_space(c, cache_keys);
@@ -453,44 +455,63 @@ int dns_cache_put(
goto fail;
}
- if (!q)
+ if (!key)
return 0;
- /* Third, add in negative entries for all keys with no RR */
- for (i = 0; i < q->n_keys; i++) {
- DnsResourceRecord *soa = NULL;
+ /* Third, add in negative entries if the key has no RR */
+ r = dns_answer_contains(answer, key);
+ if (r < 0)
+ goto fail;
+ if (r > 0)
+ return 0;
- r = dns_answer_contains(answer, q->keys[i]);
- if (r < 0)
- goto fail;
- if (r > 0)
- continue;
+ /* See https://tools.ietf.org/html/rfc2308, which
+ * say that a matching SOA record in the packet
+ * is used to to enable negative caching. */
- /* See https://tools.ietf.org/html/rfc2308, which
- * say that a matching SOA record in the packet
- * is used to to enable negative caching. */
+ r = dns_answer_find_soa(answer, key, &soa);
+ if (r < 0)
+ goto fail;
+ if (r == 0)
+ return 0;
- r = dns_answer_find_soa(answer, q->keys[i], &soa);
- if (r < 0)
- goto fail;
- if (r == 0)
- continue;
+ /* Also, if the requested key is an alias, the negative response should
+ be cached for each name in the redirect chain. Any CNAME record in
+ the response is from the redirection chain, though only the final one
+ is guaranteed to be included. This means that we cannot verify the
+ chain and that we need to cache them all as it may be incomplete. */
+ for (i = 0; i < answer->n_rrs; i++) {
+ DnsResourceRecord *answer_rr = answer->items[i].rr;
- r = dns_cache_put_negative(c, q->keys[i], rcode, timestamp, MIN(soa->soa.minimum, soa->ttl), owner_family, owner_address);
- if (r < 0)
- goto fail;
+ if (answer_rr->key->type == DNS_TYPE_CNAME) {
+ _cleanup_(dns_resource_key_unrefp) DnsResourceKey *canonical_key = NULL;
+
+ canonical_key = dns_resource_key_new_redirect(key, answer_rr);
+ if (!canonical_key)
+ goto fail;
+
+ /* Let's not add negative cache entries for records outside the current zone. */
+ if (!dns_answer_match_soa(canonical_key, soa->key))
+ continue;
+
+ r = dns_cache_put_negative(c, canonical_key, rcode, timestamp, MIN(soa->soa.minimum, soa->ttl), owner_family, owner_address);
+ if (r < 0)
+ goto fail;
+ }
}
+ r = dns_cache_put_negative(c, key, rcode, timestamp, MIN(soa->soa.minimum, soa->ttl), owner_family, owner_address);
+ if (r < 0)
+ goto fail;
+
return 0;
fail:
/* Adding all RRs failed. Let's clean up what we already
* added, just in case */
- if (q) {
- for (i = 0; i < q->n_keys; i++)
- dns_cache_remove(c, q->keys[i]);
- }
+ if (key)
+ dns_cache_remove(c, key);
for (i = 0; i < answer->n_rrs; i++)
dns_cache_remove(c, answer->items[i].rr->key);
@@ -498,6 +519,29 @@ fail:
return r;
}
+static DnsCacheItem *dns_cache_get_by_key_follow_cname(DnsCache *c, DnsResourceKey *k) {
+ _cleanup_(dns_resource_key_unrefp) DnsResourceKey *cname_key = NULL;
+ DnsCacheItem *i, *j;
+
+ assert(c);
+ assert(k);
+
+ i = hashmap_get(c->by_key, k);
+ if (i || k->type == DNS_TYPE_CNAME)
+ return i;
+
+ /* check if we have a CNAME record instead */
+ cname_key = dns_resource_key_new_cname(k);
+ if (!cname_key)
+ return NULL;
+
+ j = hashmap_get(c->by_key, cname_key);
+ if (j)
+ return j;
+
+ return i;
+}
+
int dns_cache_lookup(DnsCache *c, DnsResourceKey *key, int *rcode, DnsAnswer **ret) {
_cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
unsigned n = 0;
@@ -527,7 +571,7 @@ int dns_cache_lookup(DnsCache *c, DnsResourceKey *key, int *rcode, DnsAnswer **r
return 0;
}
- first = hashmap_get(c->by_key, key);
+ first = dns_cache_get_by_key_follow_cname(c, key);
if (!first) {
/* If one question cannot be answered we need to refresh */
diff --git a/src/resolve/resolved-dns-cache.h b/src/resolve/resolved-dns-cache.h
index 1225e58de4..164435b4fb 100644
--- a/src/resolve/resolved-dns-cache.h
+++ b/src/resolve/resolved-dns-cache.h
@@ -23,23 +23,23 @@
#include "hashmap.h"
+#include "list.h"
#include "prioq.h"
#include "time-util.h"
-#include "list.h"
typedef struct DnsCache {
Hashmap *by_key;
Prioq *by_expiry;
} DnsCache;
-#include "resolved-dns-rr.h"
-#include "resolved-dns-question.h"
#include "resolved-dns-answer.h"
+#include "resolved-dns-question.h"
+#include "resolved-dns-rr.h"
void dns_cache_flush(DnsCache *c);
void dns_cache_prune(DnsCache *c);
-int dns_cache_put(DnsCache *c, DnsQuestion *q, int rcode, DnsAnswer *answer, unsigned max_rrs, usec_t timestamp, int owner_family, const union in_addr_union *owner_address);
+int dns_cache_put(DnsCache *c, DnsResourceKey *key, int rcode, DnsAnswer *answer, unsigned max_rrs, usec_t timestamp, int owner_family, const union in_addr_union *owner_address);
int dns_cache_lookup(DnsCache *c, DnsResourceKey *key, int *rcode, DnsAnswer **answer);
int dns_cache_check_conflicts(DnsCache *cache, DnsResourceRecord *rr, int owner_family, const union in_addr_union *owner_address);
diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c
index bebd1ee4a6..f23b3cf893 100644
--- a/src/resolve/resolved-dns-packet.c
+++ b/src/resolve/resolved-dns-packet.c
@@ -19,12 +19,14 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "utf8.h"
-#include "util.h"
-#include "strv.h"
-#include "unaligned.h"
+#include "alloc-util.h"
#include "dns-domain.h"
#include "resolved-dns-packet.h"
+#include "string-table.h"
+#include "strv.h"
+#include "unaligned.h"
+#include "utf8.h"
+#include "util.h"
int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
DnsPacket *p;
diff --git a/src/resolve/resolved-dns-packet.h b/src/resolve/resolved-dns-packet.h
index fbbabaf232..73803e4e82 100644
--- a/src/resolve/resolved-dns-packet.h
+++ b/src/resolve/resolved-dns-packet.h
@@ -21,21 +21,21 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <netinet/udp.h>
#include <netinet/ip.h>
+#include <netinet/udp.h>
-#include "macro.h"
-#include "sparse-endian.h"
#include "hashmap.h"
#include "in-addr-util.h"
+#include "macro.h"
+#include "sparse-endian.h"
typedef struct DnsPacketHeader DnsPacketHeader;
typedef struct DnsPacket DnsPacket;
-#include "resolved-dns-rr.h"
-#include "resolved-dns-question.h"
-#include "resolved-dns-answer.h"
#include "resolved-def.h"
+#include "resolved-dns-answer.h"
+#include "resolved-dns-question.h"
+#include "resolved-dns-rr.h"
typedef enum DnsProtocol {
DNS_PROTOCOL_DNS,
diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c
index c0b4c8ba81..f7cb84e2a6 100644
--- a/src/resolve/resolved-dns-query.c
+++ b/src/resolve/resolved-dns-query.c
@@ -19,10 +19,10 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "hostname-util.h"
+#include "alloc-util.h"
#include "dns-domain.h"
+#include "hostname-util.h"
#include "local-addresses.h"
-
#include "resolved-dns-query.h"
/* How long to wait for the query in total */
@@ -831,7 +831,7 @@ void dns_query_ready(DnsQuery *q) {
dns_query_complete(q, state);
}
-int dns_query_cname_redirect(DnsQuery *q, const char *name) {
+int dns_query_cname_redirect(DnsQuery *q, const DnsResourceRecord *cname) {
_cleanup_(dns_question_unrefp) DnsQuestion *nq = NULL;
int r;
@@ -840,7 +840,7 @@ int dns_query_cname_redirect(DnsQuery *q, const char *name) {
if (q->n_cname_redirects > CNAME_MAX)
return -ELOOP;
- r = dns_question_cname_redirect(q->question, name, &nq);
+ r = dns_question_cname_redirect(q->question, cname, &nq);
if (r < 0)
return r;
diff --git a/src/resolve/resolved-dns-query.h b/src/resolve/resolved-dns-query.h
index 93d49301fa..2c28a7e284 100644
--- a/src/resolve/resolved-dns-query.h
+++ b/src/resolve/resolved-dns-query.h
@@ -23,12 +23,13 @@
#include "sd-bus.h"
+
#include "set.h"
typedef struct DnsQuery DnsQuery;
-#include "resolved-dns-question.h"
#include "resolved-dns-answer.h"
+#include "resolved-dns-question.h"
#include "resolved-dns-stream.h"
struct DnsQuery {
@@ -72,7 +73,7 @@ DnsQuery *dns_query_free(DnsQuery *q);
int dns_query_go(DnsQuery *q);
void dns_query_ready(DnsQuery *q);
-int dns_query_cname_redirect(DnsQuery *q, const char *name);
+int dns_query_cname_redirect(DnsQuery *q, const DnsResourceRecord *cname);
int dns_query_bus_track(DnsQuery *q, sd_bus_message *m);
diff --git a/src/resolve/resolved-dns-question.c b/src/resolve/resolved-dns-question.c
index c94928d725..48951221dc 100644
--- a/src/resolve/resolved-dns-question.c
+++ b/src/resolve/resolved-dns-question.c
@@ -19,8 +19,9 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "resolved-dns-question.h"
+#include "alloc-util.h"
#include "dns-domain.h"
+#include "resolved-dns-question.h"
DnsQuestion *dns_question_new(unsigned n) {
DnsQuestion *q;
@@ -242,13 +243,13 @@ int dns_question_is_equal(DnsQuestion *a, DnsQuestion *b) {
return 1;
}
-int dns_question_cname_redirect(DnsQuestion *q, const char *name, DnsQuestion **ret) {
+int dns_question_cname_redirect(DnsQuestion *q, const DnsResourceRecord *cname, DnsQuestion **ret) {
_cleanup_(dns_question_unrefp) DnsQuestion *n = NULL;
bool same = true;
unsigned i;
int r;
- assert(name);
+ assert(cname);
assert(ret);
if (!q) {
@@ -262,7 +263,7 @@ int dns_question_cname_redirect(DnsQuestion *q, const char *name, DnsQuestion **
}
for (i = 0; i < q->n_keys; i++) {
- r = dns_name_equal(DNS_RESOURCE_KEY_NAME(q->keys[i]), name);
+ r = dns_name_equal(DNS_RESOURCE_KEY_NAME(q->keys[i]), cname->cname.name);
if (r < 0)
return r;
@@ -286,7 +287,7 @@ int dns_question_cname_redirect(DnsQuestion *q, const char *name, DnsQuestion **
for (i = 0; i < q->n_keys; i++) {
_cleanup_(dns_resource_key_unrefp) DnsResourceKey *k = NULL;
- k = dns_resource_key_new(q->keys[i]->class, q->keys[i]->type, name);
+ k = dns_resource_key_new_redirect(q->keys[i], cname);
if (!k)
return -ENOMEM;
diff --git a/src/resolve/resolved-dns-question.h b/src/resolve/resolved-dns-question.h
index 77de0c7a2c..13cd1f20f3 100644
--- a/src/resolve/resolved-dns-question.h
+++ b/src/resolve/resolved-dns-question.h
@@ -46,6 +46,6 @@ int dns_question_is_superset(DnsQuestion *q, DnsQuestion *other);
int dns_question_contains(DnsQuestion *a, DnsResourceKey *k);
int dns_question_is_equal(DnsQuestion *a, DnsQuestion *b);
-int dns_question_cname_redirect(DnsQuestion *q, const char *name, DnsQuestion **ret);
+int dns_question_cname_redirect(DnsQuestion *q, const DnsResourceRecord *cname, DnsQuestion **ret);
DEFINE_TRIVIAL_CLEANUP_FUNC(DnsQuestion*, dns_question_unref);
diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c
index f31644eebc..ba2ea686f3 100644
--- a/src/resolve/resolved-dns-rr.c
+++ b/src/resolve/resolved-dns-rr.c
@@ -21,12 +21,14 @@
#include <math.h>
-#include "strv.h"
-
+#include "alloc-util.h"
#include "dns-domain.h"
-#include "resolved-dns-rr.h"
-#include "resolved-dns-packet.h"
#include "dns-type.h"
+#include "hexdecoct.h"
+#include "resolved-dns-packet.h"
+#include "resolved-dns-rr.h"
+#include "string-util.h"
+#include "strv.h"
DnsResourceKey* dns_resource_key_new(uint16_t class, uint16_t type, const char *name) {
DnsResourceKey *k;
@@ -48,6 +50,19 @@ DnsResourceKey* dns_resource_key_new(uint16_t class, uint16_t type, const char *
return k;
}
+DnsResourceKey* dns_resource_key_new_cname(const DnsResourceKey *key) {
+ assert(key);
+
+ return dns_resource_key_new(key->class, DNS_TYPE_CNAME, DNS_RESOURCE_KEY_NAME(key));
+}
+
+DnsResourceKey* dns_resource_key_new_redirect(const DnsResourceKey *key, const DnsResourceRecord *cname) {
+ assert(key);
+ assert(cname);
+
+ return dns_resource_key_new(key->class, key->type, cname->cname.name);
+}
+
DnsResourceKey* dns_resource_key_new_consume(uint16_t class, uint16_t type, char *name) {
DnsResourceKey *k;
@@ -133,15 +148,14 @@ int dns_resource_key_match_cname(const DnsResourceKey *key, const DnsResourceRec
return dns_name_equal(DNS_RESOURCE_KEY_NAME(rr->key), DNS_RESOURCE_KEY_NAME(key));
}
-static unsigned long dns_resource_key_hash_func(const void *i, const uint8_t hash_key[HASH_KEY_SIZE]) {
+static void dns_resource_key_hash_func(const void *i, struct siphash *state) {
const DnsResourceKey *k = i;
- unsigned long ul;
- ul = dns_name_hash_func(DNS_RESOURCE_KEY_NAME(k), hash_key);
- ul = ul * hash_key[0] + ul + k->class;
- ul = ul * hash_key[1] + ul + k->type;
+ assert(k);
- return ul;
+ dns_name_hash_func(DNS_RESOURCE_KEY_NAME(k), state);
+ siphash24_compress(&k->class, sizeof(k->class), state);
+ siphash24_compress(&k->type, sizeof(k->type), state);
}
static int dns_resource_key_compare_func(const void *a, const void *b) {
diff --git a/src/resolve/resolved-dns-rr.h b/src/resolve/resolved-dns-rr.h
index 8986a298af..a23546f757 100644
--- a/src/resolve/resolved-dns-rr.h
+++ b/src/resolve/resolved-dns-rr.h
@@ -24,9 +24,9 @@
#include <netinet/in.h>
#include "bitmap.h"
+#include "dns-type.h"
#include "hashmap.h"
#include "in-addr-util.h"
-#include "dns-type.h"
typedef struct DnsResourceKey DnsResourceKey;
typedef struct DnsResourceRecord DnsResourceRecord;
@@ -177,6 +177,8 @@ static inline const char* DNS_RESOURCE_KEY_NAME(const DnsResourceKey *key) {
}
DnsResourceKey* dns_resource_key_new(uint16_t class, uint16_t type, const char *name);
+DnsResourceKey* dns_resource_key_new_cname(const DnsResourceKey *key);
+DnsResourceKey* dns_resource_key_new_redirect(const DnsResourceKey *key, const DnsResourceRecord *cname);
DnsResourceKey* dns_resource_key_new_consume(uint16_t class, uint16_t type, char *name);
DnsResourceKey* dns_resource_key_ref(DnsResourceKey *key);
DnsResourceKey* dns_resource_key_unref(DnsResourceKey *key);
diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c
index 9e6f595a1b..873d76e40c 100644
--- a/src/resolve/resolved-dns-scope.c
+++ b/src/resolve/resolved-dns-scope.c
@@ -21,15 +21,17 @@
#include <netinet/tcp.h>
-#include "missing.h"
-#include "strv.h"
-#include "socket-util.h"
#include "af-list.h"
-#include "random-util.h"
-#include "hostname-util.h"
+#include "alloc-util.h"
#include "dns-domain.h"
-#include "resolved-llmnr.h"
+#include "fd-util.h"
+#include "hostname-util.h"
+#include "missing.h"
+#include "random-util.h"
#include "resolved-dns-scope.h"
+#include "resolved-llmnr.h"
+#include "socket-util.h"
+#include "strv.h"
#define MULTICAST_RATELIMIT_INTERVAL_USEC (1*USEC_PER_SEC)
#define MULTICAST_RATELIMIT_BURST 1000
@@ -541,6 +543,7 @@ static void dns_scope_verify_conflicts(DnsScope *s, DnsPacket *p) {
void dns_scope_process_query(DnsScope *s, DnsStream *stream, DnsPacket *p) {
_cleanup_(dns_packet_unrefp) DnsPacket *reply = NULL;
_cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL, *soa = NULL;
+ DnsResourceKey *key = NULL;
bool tentative = false;
int r, fd;
@@ -574,7 +577,10 @@ void dns_scope_process_query(DnsScope *s, DnsStream *stream, DnsPacket *p) {
return;
}
- r = dns_zone_lookup(&s->zone, p->question, &answer, &soa, &tentative);
+ assert(p->question->n_keys == 1);
+ key = p->question->keys[0];
+
+ r = dns_zone_lookup(&s->zone, key, &answer, &soa, &tentative);
if (r < 0) {
log_debug_errno(r, "Failed to lookup key: %m");
return;
diff --git a/src/resolve/resolved-dns-scope.h b/src/resolve/resolved-dns-scope.h
index b75f212897..f9b2bfda9d 100644
--- a/src/resolve/resolved-dns-scope.h
+++ b/src/resolve/resolved-dns-scope.h
@@ -25,9 +25,9 @@
typedef struct DnsScope DnsScope;
-#include "resolved-dns-server.h"
-#include "resolved-dns-packet.h"
#include "resolved-dns-cache.h"
+#include "resolved-dns-packet.h"
+#include "resolved-dns-server.h"
#include "resolved-dns-zone.h"
#include "resolved-link.h"
diff --git a/src/resolve/resolved-dns-server.c b/src/resolve/resolved-dns-server.c
index 2ff5b192df..e803f635ab 100644
--- a/src/resolve/resolved-dns-server.c
+++ b/src/resolve/resolved-dns-server.c
@@ -19,9 +19,9 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "siphash24.h"
-
+#include "alloc-util.h"
#include "resolved-dns-server.h"
+#include "siphash24.h"
/* After how much time to repeat classic DNS requests */
#define DNS_TIMEOUT_MIN_USEC (500 * USEC_PER_MSEC)
@@ -137,14 +137,13 @@ void dns_server_packet_lost(DnsServer *s, usec_t usec) {
s->resend_timeout = MIN(s->resend_timeout * 2, DNS_TIMEOUT_MAX_USEC);
}
-static unsigned long dns_server_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) {
+static void dns_server_hash_func(const void *p, struct siphash *state) {
const DnsServer *s = p;
- uint64_t u;
- siphash24((uint8_t*) &u, &s->address, FAMILY_ADDRESS_SIZE(s->family), hash_key);
- u = u * hash_key[0] + u + s->family;
+ assert(s);
- return u;
+ siphash24_compress(&s->family, sizeof(s->family), state);
+ siphash24_compress(&s->address, FAMILY_ADDRESS_SIZE(s->family), state);
}
static int dns_server_compare_func(const void *a, const void *b) {
diff --git a/src/resolve/resolved-dns-stream.c b/src/resolve/resolved-dns-stream.c
index 7f47e7223a..1c501182fb 100644
--- a/src/resolve/resolved-dns-stream.c
+++ b/src/resolve/resolved-dns-stream.c
@@ -21,6 +21,9 @@
#include <netinet/tcp.h>
+#include "alloc-util.h"
+#include "fd-util.h"
+#include "io-util.h"
#include "missing.h"
#include "resolved-dns-stream.h"
diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c
index 8092bb514d..37f47c47c0 100644
--- a/src/resolve/resolved-dns-transaction.c
+++ b/src/resolve/resolved-dns-transaction.c
@@ -20,11 +20,13 @@
***/
#include "af-list.h"
-
-#include "resolved-llmnr.h"
-#include "resolved-dns-transaction.h"
-#include "random-util.h"
+#include "alloc-util.h"
#include "dns-domain.h"
+#include "fd-util.h"
+#include "random-util.h"
+#include "resolved-dns-transaction.h"
+#include "resolved-llmnr.h"
+#include "string-table.h"
DnsTransaction* dns_transaction_free(DnsTransaction *t) {
DnsQuery *q;
@@ -458,7 +460,7 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
}
/* According to RFC 4795, section 2.9. only the RRs from the answer section shall be cached */
- dns_cache_put(&t->scope->cache, p->question, DNS_PACKET_RCODE(p), p->answer, DNS_PACKET_ANCOUNT(p), 0, p->family, &p->sender);
+ dns_cache_put(&t->scope->cache, t->key, DNS_PACKET_RCODE(p), p->answer, DNS_PACKET_ANCOUNT(p), 0, p->family, &p->sender);
if (DNS_PACKET_RCODE(p) == DNS_RCODE_SUCCESS)
dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
@@ -624,6 +626,20 @@ int dns_transaction_go(DnsTransaction *t) {
t->cached = dns_answer_unref(t->cached);
t->cached_rcode = 0;
+ /* Check the zone, but obly if this transaction is not used
+ * for probing or verifying a zone item. */
+ if (set_isempty(t->zone_items)) {
+
+ r = dns_zone_lookup(&t->scope->zone, t->key, &t->cached, NULL, NULL);
+ if (r < 0)
+ return r;
+ if (r > 0) {
+ t->cached_rcode = DNS_RCODE_SUCCESS;
+ dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
+ return 0;
+ }
+ }
+
/* Check the cache, but only if this transaction is not used
* for probing or verifying a zone item. */
if (set_isempty(t->zone_items)) {
diff --git a/src/resolve/resolved-dns-transaction.h b/src/resolve/resolved-dns-transaction.h
index acf6a6f651..d0970bd695 100644
--- a/src/resolve/resolved-dns-transaction.h
+++ b/src/resolve/resolved-dns-transaction.h
@@ -39,10 +39,10 @@ enum DnsTransactionState {
_DNS_TRANSACTION_STATE_INVALID = -1
};
-#include "resolved-dns-scope.h"
+#include "resolved-dns-answer.h"
#include "resolved-dns-packet.h"
#include "resolved-dns-question.h"
-#include "resolved-dns-answer.h"
+#include "resolved-dns-scope.h"
struct DnsTransaction {
DnsScope *scope;
diff --git a/src/resolve/resolved-dns-zone.c b/src/resolve/resolved-dns-zone.c
index 674bb6af28..a021ecb93d 100644
--- a/src/resolve/resolved-dns-zone.c
+++ b/src/resolve/resolved-dns-zone.c
@@ -19,11 +19,12 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "list.h"
-
-#include "resolved-dns-zone.h"
+#include "alloc-util.h"
#include "dns-domain.h"
+#include "list.h"
#include "resolved-dns-packet.h"
+#include "resolved-dns-zone.h"
+#include "string-util.h"
/* Never allow more than 1K entries */
#define ZONE_MAX 1024
@@ -90,11 +91,8 @@ void dns_zone_flush(DnsZone *z) {
assert(hashmap_size(z->by_key) == 0);
assert(hashmap_size(z->by_name) == 0);
- hashmap_free(z->by_key);
- z->by_key = NULL;
-
- hashmap_free(z->by_name);
- z->by_name = NULL;
+ z->by_key = hashmap_free(z->by_key);
+ z->by_name = hashmap_free(z->by_name);
}
static DnsZoneItem* dns_zone_get(DnsZone *z, DnsResourceRecord *rr) {
@@ -285,97 +283,76 @@ int dns_zone_put(DnsZone *z, DnsScope *s, DnsResourceRecord *rr, bool probe) {
return 0;
}
-int dns_zone_lookup(DnsZone *z, DnsQuestion *q, DnsAnswer **ret_answer, DnsAnswer **ret_soa, bool *ret_tentative) {
+int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, DnsAnswer **ret_answer, DnsAnswer **ret_soa, bool *ret_tentative) {
_cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL, *soa = NULL;
- unsigned i, n_answer = 0, n_soa = 0;
- bool tentative = true;
+ unsigned n_answer = 0;
+ DnsZoneItem *j, *first;
+ bool tentative = true, need_soa = false;
int r;
assert(z);
- assert(q);
+ assert(key);
assert(ret_answer);
- assert(ret_soa);
- if (q->n_keys <= 0) {
- *ret_answer = NULL;
- *ret_soa = NULL;
+ /* First iteration, count what we have */
- if (ret_tentative)
- *ret_tentative = false;
+ if (key->type == DNS_TYPE_ANY || key->class == DNS_CLASS_ANY) {
+ bool found = false, added = false;
+ int k;
- return 0;
- }
+ /* If this is a generic match, then we have to
+ * go through the list by the name and look
+ * for everything manually */
- /* First iteration, count what we have */
- for (i = 0; i < q->n_keys; i++) {
- DnsZoneItem *j, *first;
-
- if (q->keys[i]->type == DNS_TYPE_ANY ||
- q->keys[i]->class == DNS_CLASS_ANY) {
- bool found = false, added = false;
- int k;
+ first = hashmap_get(z->by_name, DNS_RESOURCE_KEY_NAME(key));
+ LIST_FOREACH(by_name, j, first) {
+ if (!IN_SET(j->state, DNS_ZONE_ITEM_PROBING, DNS_ZONE_ITEM_ESTABLISHED, DNS_ZONE_ITEM_VERIFYING))
+ continue;
- /* If this is a generic match, then we have to
- * go through the list by the name and look
- * for everything manually */
+ found = true;
- first = hashmap_get(z->by_name, DNS_RESOURCE_KEY_NAME(q->keys[i]));
- LIST_FOREACH(by_name, j, first) {
- if (!IN_SET(j->state, DNS_ZONE_ITEM_PROBING, DNS_ZONE_ITEM_ESTABLISHED, DNS_ZONE_ITEM_VERIFYING))
- continue;
+ k = dns_resource_key_match_rr(key, j->rr);
+ if (k < 0)
+ return k;
+ if (k > 0) {
+ n_answer++;
+ added = true;
+ }
- found = true;
+ }
- k = dns_resource_key_match_rr(q->keys[i], j->rr);
- if (k < 0)
- return k;
- if (k > 0) {
- n_answer++;
- added = true;
- }
+ if (found && !added)
+ need_soa = true;
- }
+ } else {
+ bool found = false;
- if (found && !added)
- n_soa++;
+ /* If this is a specific match, then look for
+ * the right key immediately */
- } else {
- bool found = false;
+ first = hashmap_get(z->by_key, key);
+ LIST_FOREACH(by_key, j, first) {
+ if (!IN_SET(j->state, DNS_ZONE_ITEM_PROBING, DNS_ZONE_ITEM_ESTABLISHED, DNS_ZONE_ITEM_VERIFYING))
+ continue;
- /* If this is a specific match, then look for
- * the right key immediately */
+ found = true;
+ n_answer++;
+ }
- first = hashmap_get(z->by_key, q->keys[i]);
- LIST_FOREACH(by_key, j, first) {
+ if (!found) {
+ first = hashmap_get(z->by_name, DNS_RESOURCE_KEY_NAME(key));
+ LIST_FOREACH(by_name, j, first) {
if (!IN_SET(j->state, DNS_ZONE_ITEM_PROBING, DNS_ZONE_ITEM_ESTABLISHED, DNS_ZONE_ITEM_VERIFYING))
continue;
- found = true;
- n_answer++;
- }
-
- if (!found) {
- first = hashmap_get(z->by_name, DNS_RESOURCE_KEY_NAME(q->keys[i]));
- LIST_FOREACH(by_name, j, first) {
- if (!IN_SET(j->state, DNS_ZONE_ITEM_PROBING, DNS_ZONE_ITEM_ESTABLISHED, DNS_ZONE_ITEM_VERIFYING))
- continue;
-
- n_soa++;
- break;
- }
+ need_soa = true;
+ break;
}
}
}
- if (n_answer <= 0 && n_soa <= 0) {
- *ret_answer = NULL;
- *ret_soa = NULL;
-
- if (ret_tentative)
- *ret_tentative = false;
-
- return 0;
- }
+ if (n_answer <= 0 && !need_soa)
+ goto return_empty;
if (n_answer > 0) {
answer = dns_answer_new(n_answer);
@@ -383,99 +360,113 @@ int dns_zone_lookup(DnsZone *z, DnsQuestion *q, DnsAnswer **ret_answer, DnsAnswe
return -ENOMEM;
}
- if (n_soa > 0) {
- soa = dns_answer_new(n_soa);
+ if (need_soa) {
+ soa = dns_answer_new(1);
if (!soa)
return -ENOMEM;
}
/* Second iteration, actually add the RRs to the answers */
- for (i = 0; i < q->n_keys; i++) {
- DnsZoneItem *j, *first;
-
- if (q->keys[i]->type == DNS_TYPE_ANY ||
- q->keys[i]->class == DNS_CLASS_ANY) {
- bool found = false, added = false;
- int k;
-
- first = hashmap_get(z->by_name, DNS_RESOURCE_KEY_NAME(q->keys[i]));
- LIST_FOREACH(by_name, j, first) {
- if (!IN_SET(j->state, DNS_ZONE_ITEM_PROBING, DNS_ZONE_ITEM_ESTABLISHED, DNS_ZONE_ITEM_VERIFYING))
- continue;
+ if (key->type == DNS_TYPE_ANY || key->class == DNS_CLASS_ANY) {
+ bool found = false, added = false;
+ int k;
- found = true;
-
- if (j->state != DNS_ZONE_ITEM_PROBING)
- tentative = false;
+ first = hashmap_get(z->by_name, DNS_RESOURCE_KEY_NAME(key));
+ LIST_FOREACH(by_name, j, first) {
+ if (!IN_SET(j->state, DNS_ZONE_ITEM_PROBING, DNS_ZONE_ITEM_ESTABLISHED, DNS_ZONE_ITEM_VERIFYING))
+ continue;
- k = dns_resource_key_match_rr(q->keys[i], j->rr);
- if (k < 0)
- return k;
- if (k > 0) {
- r = dns_answer_add(answer, j->rr, 0);
- if (r < 0)
- return r;
+ found = true;
- added = true;
- }
- }
+ if (j->state != DNS_ZONE_ITEM_PROBING)
+ tentative = false;
- if (found && !added) {
- r = dns_answer_add_soa(soa, DNS_RESOURCE_KEY_NAME(q->keys[i]), LLMNR_DEFAULT_TTL);
+ k = dns_resource_key_match_rr(key, j->rr);
+ if (k < 0)
+ return k;
+ if (k > 0) {
+ r = dns_answer_add(answer, j->rr, 0);
if (r < 0)
return r;
+
+ added = true;
}
- } else {
- bool found = false;
+ }
- first = hashmap_get(z->by_key, q->keys[i]);
- LIST_FOREACH(by_key, j, first) {
- if (!IN_SET(j->state, DNS_ZONE_ITEM_PROBING, DNS_ZONE_ITEM_ESTABLISHED, DNS_ZONE_ITEM_VERIFYING))
- continue;
+ if (found && !added) {
+ r = dns_answer_add_soa(soa, DNS_RESOURCE_KEY_NAME(key), LLMNR_DEFAULT_TTL);
+ if (r < 0)
+ return r;
+ }
+ } else {
+ bool found = false;
- found = true;
+ first = hashmap_get(z->by_key, key);
+ LIST_FOREACH(by_key, j, first) {
+ if (!IN_SET(j->state, DNS_ZONE_ITEM_PROBING, DNS_ZONE_ITEM_ESTABLISHED, DNS_ZONE_ITEM_VERIFYING))
+ continue;
- if (j->state != DNS_ZONE_ITEM_PROBING)
- tentative = false;
+ found = true;
- r = dns_answer_add(answer, j->rr, 0);
- if (r < 0)
- return r;
- }
+ if (j->state != DNS_ZONE_ITEM_PROBING)
+ tentative = false;
- if (!found) {
- bool add_soa = false;
+ r = dns_answer_add(answer, j->rr, 0);
+ if (r < 0)
+ return r;
+ }
+
+ if (!found) {
+ bool add_soa = false;
- first = hashmap_get(z->by_name, DNS_RESOURCE_KEY_NAME(q->keys[i]));
- LIST_FOREACH(by_name, j, first) {
- if (!IN_SET(j->state, DNS_ZONE_ITEM_PROBING, DNS_ZONE_ITEM_ESTABLISHED, DNS_ZONE_ITEM_VERIFYING))
- continue;
+ first = hashmap_get(z->by_name, DNS_RESOURCE_KEY_NAME(key));
+ LIST_FOREACH(by_name, j, first) {
+ if (!IN_SET(j->state, DNS_ZONE_ITEM_PROBING, DNS_ZONE_ITEM_ESTABLISHED, DNS_ZONE_ITEM_VERIFYING))
+ continue;
- if (j->state != DNS_ZONE_ITEM_PROBING)
- tentative = false;
+ if (j->state != DNS_ZONE_ITEM_PROBING)
+ tentative = false;
- add_soa = true;
- }
+ add_soa = true;
+ }
- if (add_soa) {
- r = dns_answer_add_soa(soa, DNS_RESOURCE_KEY_NAME(q->keys[i]), LLMNR_DEFAULT_TTL);
- if (r < 0)
- return r;
- }
+ if (add_soa) {
+ r = dns_answer_add_soa(soa, DNS_RESOURCE_KEY_NAME(key), LLMNR_DEFAULT_TTL);
+ if (r < 0)
+ return r;
}
}
}
+ /* If the caller sets ret_tentative to NULL, then use this as
+ * indication to not return tentative entries */
+
+ if (!ret_tentative && tentative)
+ goto return_empty;
+
*ret_answer = answer;
answer = NULL;
- *ret_soa = soa;
- soa = NULL;
+ if (ret_soa) {
+ *ret_soa = soa;
+ soa = NULL;
+ }
if (ret_tentative)
*ret_tentative = tentative;
return 1;
+
+return_empty:
+ *ret_answer = NULL;
+
+ if (ret_soa)
+ *ret_soa = NULL;
+
+ if (ret_tentative)
+ *ret_tentative = false;
+
+ return 0;
}
void dns_zone_item_conflict(DnsZoneItem *i) {
diff --git a/src/resolve/resolved-dns-zone.h b/src/resolve/resolved-dns-zone.h
index 495d17cdb1..44a8624c30 100644
--- a/src/resolve/resolved-dns-zone.h
+++ b/src/resolve/resolved-dns-zone.h
@@ -31,9 +31,9 @@ typedef struct DnsZone {
typedef struct DnsZoneItem DnsZoneItem;
typedef enum DnsZoneItemState DnsZoneItemState;
-#include "resolved-dns-rr.h"
-#include "resolved-dns-question.h"
#include "resolved-dns-answer.h"
+#include "resolved-dns-question.h"
+#include "resolved-dns-rr.h"
#include "resolved-dns-transaction.h"
/* RFC 4795 Section 2.8. suggests a TTL of 30s by default */
@@ -67,7 +67,7 @@ void dns_zone_flush(DnsZone *z);
int dns_zone_put(DnsZone *z, DnsScope *s, DnsResourceRecord *rr, bool probe);
void dns_zone_remove_rr(DnsZone *z, DnsResourceRecord *rr);
-int dns_zone_lookup(DnsZone *z, DnsQuestion *q, DnsAnswer **answer, DnsAnswer **soa, bool *tentative);
+int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, DnsAnswer **answer, DnsAnswer **soa, bool *tentative);
void dns_zone_item_conflict(DnsZoneItem *i);
void dns_zone_item_ready(DnsZoneItem *i);
diff --git a/src/resolve/resolved-link.c b/src/resolve/resolved-link.c
index 47f461a37d..2892641075 100644
--- a/src/resolve/resolved-link.c
+++ b/src/resolve/resolved-link.c
@@ -22,9 +22,13 @@
#include <net/if.h>
#include "sd-network.h"
-#include "strv.h"
+
+#include "alloc-util.h"
#include "missing.h"
+#include "parse-util.h"
#include "resolved-link.h"
+#include "string-util.h"
+#include "strv.h"
int link_new(Manager *m, Link **ret, int ifindex) {
_cleanup_(link_freep) Link *l = NULL;
@@ -238,8 +242,7 @@ static int link_update_domains(Link *l) {
if (!l->unicast_scope)
return 0;
- strv_free(l->unicast_scope->domains);
- l->unicast_scope->domains = NULL;
+ l->unicast_scope->domains = strv_free(l->unicast_scope->domains);
r = sd_network_link_get_domains(l->ifindex,
&l->unicast_scope->domains);
diff --git a/src/resolve/resolved-llmnr.c b/src/resolve/resolved-llmnr.c
index 8afaf8db6e..6a7ff9d245 100644
--- a/src/resolve/resolved-llmnr.c
+++ b/src/resolve/resolved-llmnr.c
@@ -19,11 +19,12 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <resolv.h>
#include <netinet/in.h>
+#include <resolv.h>
-#include "resolved-manager.h"
+#include "fd-util.h"
#include "resolved-llmnr.h"
+#include "resolved-manager.h"
void manager_llmnr_stop(Manager *m) {
assert(m);
diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c
index de924e3ed9..a588538b52 100644
--- a/src/resolve/resolved-manager.c
+++ b/src/resolve/resolved-manager.c
@@ -19,26 +19,31 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <netinet/in.h>
+#include <poll.h>
#include <resolv.h>
#include <sys/ioctl.h>
-#include <poll.h>
-#include <netinet/in.h>
-#include "netlink-util.h"
-#include "network-internal.h"
-#include "socket-util.h"
#include "af-list.h"
-#include "utf8.h"
+#include "alloc-util.h"
+#include "dns-domain.h"
+#include "fd-util.h"
#include "fileio-label.h"
+#include "hostname-util.h"
+#include "io-util.h"
+#include "netlink-util.h"
+#include "network-internal.h"
#include "ordered-set.h"
+#include "parse-util.h"
#include "random-util.h"
-#include "hostname-util.h"
-
-#include "dns-domain.h"
-#include "resolved-conf.h"
#include "resolved-bus.h"
-#include "resolved-manager.h"
+#include "resolved-conf.h"
#include "resolved-llmnr.h"
+#include "resolved-manager.h"
+#include "socket-util.h"
+#include "string-table.h"
+#include "string-util.h"
+#include "utf8.h"
#define SEND_TIMEOUT_USEC (200 * USEC_PER_MSEC)
diff --git a/src/resolve/resolved-manager.h b/src/resolve/resolved-manager.h
index fe7fe99505..074ce6c63d 100644
--- a/src/resolve/resolved-manager.h
+++ b/src/resolve/resolved-manager.h
@@ -22,10 +22,11 @@
***/
#include "sd-event.h"
-#include "sd-network.h"
#include "sd-netlink.h"
-#include "list.h"
+#include "sd-network.h"
+
#include "hashmap.h"
+#include "list.h"
typedef struct Manager Manager;
typedef enum Support Support;
diff --git a/src/resolve/resolved.c b/src/resolve/resolved.c
index 32e61af925..7ba0546f4a 100644
--- a/src/resolve/resolved.c
+++ b/src/resolve/resolved.c
@@ -19,15 +19,16 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "sd-event.h"
#include "sd-daemon.h"
+#include "sd-event.h"
+
+#include "capability-util.h"
#include "mkdir.h"
-#include "capability.h"
+#include "resolved-conf.h"
+#include "resolved-manager.h"
#include "selinux-util.h"
#include "signal-util.h"
-
-#include "resolved-manager.h"
-#include "resolved-conf.h"
+#include "user-util.h"
int main(int argc, char *argv[]) {
_cleanup_(manager_freep) Manager *m = NULL;