Compare commits

...

9 Commits

Author SHA1 Message Date
Lennart Poettering eaa269484b resolved: fix non-initialized memory access
Fix for bug introduced in 1ed314087f.
2020-11-06 13:58:20 -08:00
Lennart Poettering 2386d1c1d3
Merge pull request #17534 from poettering/resolved-more-tweaks
seven smaller resolved tweaks
2020-11-06 22:39:09 +01:00
Lennart Poettering 76f772298e resolved: slightly extend debug log output about outgoing messages 2020-11-06 14:43:05 +01:00
Lennart Poettering 088648d081 resolved: don't resolve "local." via LLMNR
It's the mDNS top-level domain, hence don't consider it for LLMNR, ever.

Fixes: #16233
2020-11-06 14:43:01 +01:00
Lennart Poettering dc194dce80 resolved: add comments for various query flags 2020-11-06 14:42:56 +01:00
Lennart Poettering 5cdcac6cf6 resolved: show all answer flags when dumping answer 2020-11-06 14:42:53 +01:00
Lennart Poettering 032b398224 resolved: add minor optimization path to dns_answer_merge() 2020-11-06 14:42:49 +01:00
Lennart Poettering 02c205359b resolved: suppress misleading debug message about ignored resolv.conf line 2020-11-06 14:42:45 +01:00
Lennart Poettering 8d50c14252 errno: ETIMEDOUT is also a connection error 2020-11-06 14:42:18 +01:00
7 changed files with 57 additions and 21 deletions

View File

@ -50,7 +50,10 @@ static inline int errno_or_else(int fallback) {
/* Hint #1: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5. /* Hint #1: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5.
* *
* Hint #2: The kernel sends e.g., EHOSTUNREACH or ENONET to userspace in some ICMP error cases. See the * Hint #2: The kernel sends e.g., EHOSTUNREACH or ENONET to userspace in some ICMP error cases. See the
* icmp_err_convert[] in net/ipv4/icmp.c in the kernel sources */ * icmp_err_convert[] in net/ipv4/icmp.c in the kernel sources.
*
* Hint #3: When asynchronous connect() on TCP fails because the host never acknowledges a single packet,
* kernel tells us that with ETIMEDOUT, see tcp(7). */
static inline bool ERRNO_IS_DISCONNECT(int r) { static inline bool ERRNO_IS_DISCONNECT(int r) {
return IN_SET(abs(r), return IN_SET(abs(r),
ECONNABORTED, ECONNABORTED,
@ -66,7 +69,8 @@ static inline bool ERRNO_IS_DISCONNECT(int r) {
ENOTCONN, ENOTCONN,
EPIPE, EPIPE,
EPROTO, EPROTO,
ESHUTDOWN); ESHUTDOWN,
ETIMEDOUT);
} }
/* Transient errors we might get on accept() that we should ignore. As per error handling comment in /* Transient errors we might get on accept() that we should ignore. As per error handling comment in

View File

@ -5,20 +5,30 @@
#include "time-util.h" #include "time-util.h"
#define SD_RESOLVED_DNS (UINT64_C(1) << 0) /* Input + Output: The various protocols we can use */
#define SD_RESOLVED_LLMNR_IPV4 (UINT64_C(1) << 1) #define SD_RESOLVED_DNS (UINT64_C(1) << 0)
#define SD_RESOLVED_LLMNR_IPV6 (UINT64_C(1) << 2) #define SD_RESOLVED_LLMNR_IPV4 (UINT64_C(1) << 1)
#define SD_RESOLVED_MDNS_IPV4 (UINT64_C(1) << 3) #define SD_RESOLVED_LLMNR_IPV6 (UINT64_C(1) << 2)
#define SD_RESOLVED_MDNS_IPV6 (UINT64_C(1) << 4) #define SD_RESOLVED_MDNS_IPV4 (UINT64_C(1) << 3)
#define SD_RESOLVED_NO_CNAME (UINT64_C(1) << 5) #define SD_RESOLVED_MDNS_IPV6 (UINT64_C(1) << 4)
#define SD_RESOLVED_NO_TXT (UINT64_C(1) << 6)
#define SD_RESOLVED_NO_ADDRESS (UINT64_C(1) << 7)
#define SD_RESOLVED_NO_SEARCH (UINT64_C(1) << 8)
#define SD_RESOLVED_AUTHENTICATED (UINT64_C(1) << 9)
#define SD_RESOLVED_LLMNR (SD_RESOLVED_LLMNR_IPV4|SD_RESOLVED_LLMNR_IPV6) /* Input: Don't follow CNAMEs/DNAMEs */
#define SD_RESOLVED_MDNS (SD_RESOLVED_MDNS_IPV4|SD_RESOLVED_MDNS_IPV6) #define SD_RESOLVED_NO_CNAME (UINT64_C(1) << 5)
#define SD_RESOLVED_PROTOCOLS_ALL (SD_RESOLVED_MDNS|SD_RESOLVED_LLMNR|SD_RESOLVED_DNS) /* Input: When doing service (SRV) resolving, don't resolve associated mDNS-style TXT records */
#define SD_RESOLVED_NO_TXT (UINT64_C(1) << 6)
/* Input: When doing service (SRV) resolving, don't resolve A/AAA RR for included hostname */
#define SD_RESOLVED_NO_ADDRESS (UINT64_C(1) << 7)
/* Input: Don't apply search domain logic to request */
#define SD_RESOLVED_NO_SEARCH (UINT64_C(1) << 8)
/* Output: Result is authenticated */
#define SD_RESOLVED_AUTHENTICATED (UINT64_C(1) << 9)
#define SD_RESOLVED_LLMNR (SD_RESOLVED_LLMNR_IPV4|SD_RESOLVED_LLMNR_IPV6)
#define SD_RESOLVED_MDNS (SD_RESOLVED_MDNS_IPV4|SD_RESOLVED_MDNS_IPV6)
#define SD_RESOLVED_PROTOCOLS_ALL (SD_RESOLVED_MDNS|SD_RESOLVED_LLMNR|SD_RESOLVED_DNS)
#define SD_RESOLVED_QUERY_TIMEOUT_USEC (120 * USEC_PER_SEC) #define SD_RESOLVED_QUERY_TIMEOUT_USEC (120 * USEC_PER_SEC)

View File

@ -321,6 +321,11 @@ int dns_answer_merge(DnsAnswer *a, DnsAnswer *b, DnsAnswer **ret) {
assert(ret); assert(ret);
if (a == b) {
*ret = dns_answer_ref(a);
return 0;
}
if (dns_answer_size(a) <= 0) { if (dns_answer_size(a) <= 0) {
*ret = dns_answer_ref(b); *ret = dns_answer_ref(b);
return 0; return 0;
@ -709,7 +714,7 @@ void dns_answer_dump(DnsAnswer *answer, FILE *f) {
fputs(t, f); fputs(t, f);
if (ifindex != 0 || flags & (DNS_ANSWER_AUTHENTICATED|DNS_ANSWER_CACHEABLE|DNS_ANSWER_SHARED_OWNER)) if (ifindex != 0 || flags != 0)
fputs("\t;", f); fputs("\t;", f);
if (ifindex != 0) if (ifindex != 0)
@ -720,6 +725,10 @@ void dns_answer_dump(DnsAnswer *answer, FILE *f) {
fputs(" cacheable", f); fputs(" cacheable", f);
if (flags & DNS_ANSWER_SHARED_OWNER) if (flags & DNS_ANSWER_SHARED_OWNER)
fputs(" shared-owner", f); fputs(" shared-owner", f);
if (flags & DNS_ANSWER_CACHE_FLUSH)
fputs(" cache-flush", f);
if (flags & DNS_ANSWER_GOODBYE)
fputs(" goodbye", f);
fputc('\n', f); fputc('\n', f);
} }

View File

@ -531,9 +531,6 @@ static int dns_cache_put_negative(
.type = .type =
rcode == DNS_RCODE_SUCCESS ? DNS_CACHE_NODATA : rcode == DNS_RCODE_SUCCESS ? DNS_CACHE_NODATA :
rcode == DNS_RCODE_NXDOMAIN ? DNS_CACHE_NXDOMAIN : DNS_CACHE_RCODE, rcode == DNS_RCODE_NXDOMAIN ? DNS_CACHE_NXDOMAIN : DNS_CACHE_RCODE,
.until =
i->type == DNS_CACHE_RCODE ? timestamp + CACHE_TTL_STRANGE_RCODE_USEC :
calculate_until(soa, nsec_ttl, timestamp, true),
.authenticated = authenticated, .authenticated = authenticated,
.owner_family = owner_family, .owner_family = owner_family,
.owner_address = *owner_address, .owner_address = *owner_address,
@ -541,6 +538,10 @@ static int dns_cache_put_negative(
.rcode = rcode, .rcode = rcode,
}; };
i->until =
i->type == DNS_CACHE_RCODE ? timestamp + CACHE_TTL_STRANGE_RCODE_USEC :
calculate_until(soa, nsec_ttl, timestamp, true);
if (i->type == DNS_CACHE_NXDOMAIN) { if (i->type == DNS_CACHE_NXDOMAIN) {
/* NXDOMAIN entries should apply equally to all types, so we use ANY as /* NXDOMAIN entries should apply equally to all types, so we use ANY as
* a pseudo type for this purpose here. */ * a pseudo type for this purpose here. */

View File

@ -589,6 +589,7 @@ DnsScopeMatch dns_scope_good_domain(
if ((dns_name_is_single_label(domain) && /* only resolve single label names via LLMNR */ if ((dns_name_is_single_label(domain) && /* only resolve single label names via LLMNR */
!is_gateway_hostname(domain) && /* don't resolve "gateway" with LLMNR, let nss-myhostname handle this */ !is_gateway_hostname(domain) && /* don't resolve "gateway" with LLMNR, let nss-myhostname handle this */
dns_name_equal(domain, "local") == 0 && /* don't resolve "local" with LLMNR, it's the top-level domain of mDNS after all, see above */
manager_is_own_hostname(s->manager, domain) <= 0)) /* never resolve the local hostname via LLMNR */ manager_is_own_hostname(s->manager, domain) <= 0)) /* never resolve the local hostname via LLMNR */
return DNS_SCOPE_YES_BASE + 1; /* Return +1, as we consider ourselves authoritative return DNS_SCOPE_YES_BASE + 1; /* Return +1, as we consider ourselves authoritative
* for single-label names, i.e. one label. This is * for single-label names, i.e. one label. This is

View File

@ -919,7 +919,11 @@ static int write_loop(int fd, void *message, size_t length) {
int manager_write(Manager *m, int fd, DnsPacket *p) { int manager_write(Manager *m, int fd, DnsPacket *p) {
int r; int r;
log_debug("Sending %s packet with id %" PRIu16 ".", DNS_PACKET_QR(p) ? "response" : "query", DNS_PACKET_ID(p)); log_debug("Sending %s%s packet with id %" PRIu16 " of size %zu.",
DNS_PACKET_TC(p) ? "truncated (!) " : "",
DNS_PACKET_QR(p) ? "response" : "query",
DNS_PACKET_ID(p),
p->size);
r = write_loop(fd, DNS_PACKET_DATA(p), p->size); r = write_loop(fd, DNS_PACKET_DATA(p), p->size);
if (r < 0) if (r < 0)
@ -1055,7 +1059,12 @@ int manager_send(
assert(port > 0); assert(port > 0);
assert(p); assert(p);
log_debug("Sending %s packet with id %" PRIu16 " on interface %i/%s.", DNS_PACKET_QR(p) ? "response" : "query", DNS_PACKET_ID(p), ifindex, af_to_name(family)); log_debug("Sending %s%s packet with id %" PRIu16 " on interface %i/%s of size %zu.",
DNS_PACKET_TC(p) ? "truncated (!) " : "",
DNS_PACKET_QR(p) ? "response" : "query",
DNS_PACKET_ID(p),
ifindex, af_to_name(family),
p->size);
if (family == AF_INET) if (family == AF_INET)
return manager_ipv4_send(m, fd, ifindex, &destination->in, port, source ? &source->in : NULL, p); return manager_ipv4_send(m, fd, ifindex, &destination->in, port, source ? &source->in : NULL, p);

View File

@ -156,6 +156,8 @@ int manager_read_resolv_conf(Manager *m) {
r = manager_parse_search_domains_and_warn(m, a); r = manager_parse_search_domains_and_warn(m, a);
if (r < 0) if (r < 0)
log_warning_errno(r, "Failed to parse search domain string '%s', ignoring.", a); log_warning_errno(r, "Failed to parse search domain string '%s', ignoring.", a);
continue;
} }
log_syntax(NULL, LOG_DEBUG, "/etc/resolv.conf", n, 0, "Ignoring resolv.conf line: %s", l); log_syntax(NULL, LOG_DEBUG, "/etc/resolv.conf", n, 0, "Ignoring resolv.conf line: %s", l);