diff options
-rw-r--r-- | src/resolve/resolved-dns-stream.c | 8 | ||||
-rw-r--r-- | src/resolve/resolved-dns-stream.h | 14 | ||||
-rw-r--r-- | src/resolve/resolved-dns-stub.c | 15 | ||||
-rw-r--r-- | src/resolve/resolved-dns-transaction.c | 11 | ||||
-rw-r--r-- | src/resolve/resolved-llmnr.c | 2 |
5 files changed, 38 insertions, 12 deletions
diff --git a/src/resolve/resolved-dns-stream.c b/src/resolve/resolved-dns-stream.c index 3e6505cd75..719f6219bf 100644 --- a/src/resolve/resolved-dns-stream.c +++ b/src/resolve/resolved-dns-stream.c @@ -10,7 +10,6 @@ #include "resolved-dns-stream.h" #include "resolved-manager.h" -#define DNS_STREAM_TIMEOUT_USEC (10 * USEC_PER_SEC) #define DNS_STREAMS_MAX 128 #define DNS_QUERIES_PER_STREAM 32 @@ -437,7 +436,7 @@ static int on_stream_io(sd_event_source *es, int fd, uint32_t revents, void *use /* If we did something, let's restart the timeout event source */ if (progressed && s->timeout_event_source) { - r = sd_event_source_set_time_relative(s->timeout_event_source, DNS_STREAM_TIMEOUT_USEC); + r = sd_event_source_set_time_relative(s->timeout_event_source, DNS_STREAM_ESTABLISHED_TIMEOUT_USEC); if (r < 0) log_warning_errno(errno, "Couldn't restart TCP connection timeout, ignoring: %m"); } @@ -482,7 +481,8 @@ int dns_stream_new( DnsStreamType type, DnsProtocol protocol, int fd, - const union sockaddr_union *tfo_address) { + const union sockaddr_union *tfo_address, + usec_t connect_timeout_usec) { _cleanup_(dns_stream_unrefp) DnsStream *s = NULL; int r; @@ -523,7 +523,7 @@ int dns_stream_new( m->event, &s->timeout_event_source, clock_boottime_or_monotonic(), - DNS_STREAM_TIMEOUT_USEC, 0, + connect_timeout_usec, 0, on_stream_timeout, s); if (r < 0) return r; diff --git a/src/resolve/resolved-dns-stream.h b/src/resolve/resolved-dns-stream.h index 470d446ddb..96b977f628 100644 --- a/src/resolve/resolved-dns-stream.h +++ b/src/resolve/resolved-dns-stream.h @@ -15,6 +15,18 @@ typedef struct DnsStubListenerExtra DnsStubListenerExtra; #include "resolved-dns-packet.h" #include "resolved-dnstls.h" +/* Various timeouts for establishing TCP connections. First the default time-out for that. */ +#define DNS_STREAM_DEFAULT_TIMEOUT_USEC (10 * USEC_PER_SEC) + +/* In the DNS stub, be more friendly for incoming connections, than we are to ourselves for outgoing ones */ +#define DNS_STREAM_STUB_TIMEOUT_USEC (30 * USEC_PER_SEC) + +/* In opportunistic TLS mode, lower timeouts */ +#define DNS_STREAM_OPPORTUNISTIC_TLS_TIMEOUT_USEC (3 * USEC_PER_SEC) + +/* Once connections are established apply this timeout once nothing happens anymore */ +#define DNS_STREAM_ESTABLISHED_TIMEOUT_USEC (10 * USEC_PER_SEC) + typedef enum DnsStreamType { DNS_STREAM_LOOKUP, /* Outgoing connection to a classic DNS server */ DNS_STREAM_LLMNR_SEND, /* Outgoing LLMNR TCP lookup */ @@ -81,7 +93,7 @@ struct DnsStream { LIST_FIELDS(DnsStream, streams); }; -int dns_stream_new(Manager *m, DnsStream **s, DnsStreamType type, DnsProtocol protocol, int fd, const union sockaddr_union *tfo_address); +int dns_stream_new(Manager *m, DnsStream **s, DnsStreamType type, DnsProtocol protocol, int fd, const union sockaddr_union *tfo_address, usec_t timeout); #if ENABLE_DNS_OVER_TLS int dns_stream_connect_tls(DnsStream *s, void *tls_session); #endif diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c index 09fd7d2418..73590e3f9b 100644 --- a/src/resolve/resolved-dns-stub.c +++ b/src/resolve/resolved-dns-stub.c @@ -950,10 +950,8 @@ static void dns_stub_process_query(Manager *m, DnsStubListenerExtra *l, DnsStrea _cleanup_free_ char *dipa = NULL; r = in_addr_to_string(p->family, &p->destination, &dipa); - if (r < 0) { - log_error_errno(r, "Failed to format destination address: %m"); - return; - } + if (r < 0) + return (void) log_error_errno(r, "Failed to format destination address: %m"); log_debug("Got request to DNS proxy address 127.0.0.54, enabling bypass logic."); bypass = true; @@ -1076,7 +1074,7 @@ static int on_dns_stub_stream_internal(sd_event_source *s, int fd, uint32_t reve return -errno; } - r = dns_stream_new(m, &stream, DNS_STREAM_STUB, DNS_PROTOCOL_DNS, cfd, NULL); + r = dns_stream_new(m, &stream, DNS_STREAM_STUB, DNS_PROTOCOL_DNS, cfd, NULL, DNS_STREAM_STUB_TIMEOUT_USEC); if (r < 0) { safe_close(cfd); return r; @@ -1150,6 +1148,9 @@ static int manager_dns_stub_fd( union sockaddr_union sa; int r; + assert(m); + assert(listen_addr); + if (type == SOCK_DGRAM) event_source = address_is_proxy(family, listen_addr) ? &m->dns_proxy_stub_udp_event_source : &m->dns_stub_udp_event_source; else if (type == SOCK_STREAM) @@ -1188,6 +1189,10 @@ static int manager_dns_stub_fd( if (r < 0) return r; } else if (type == SOCK_DGRAM) { + /* Turn off Path MTU Discovery for UDP, for security reasons. See socket_disable_pmtud() for + * a longer discussion. (We only do this for sockets that are potentially externally + * accessible, i.e. the proxy stub one. For the non-proxy one we instead set the TTL to 1, + * see above, so that packets don't get routed at all.) */ r = socket_disable_pmtud(fd, family); if (r < 0) log_debug_errno(r, "Failed to disable UDP PMTUD, ignoring: %m"); diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c index 594ce5e27b..0cf9912712 100644 --- a/src/resolve/resolved-dns-transaction.c +++ b/src/resolve/resolved-dns-transaction.c @@ -673,6 +673,7 @@ static uint16_t dns_transaction_port(DnsTransaction *t) { } static int dns_transaction_emit_tcp(DnsTransaction *t) { + usec_t stream_timeout_usec = DNS_STREAM_DEFAULT_TIMEOUT_USEC; _cleanup_(dns_stream_unrefp) DnsStream *s = NULL; _cleanup_close_ int fd = -1; union sockaddr_union sa; @@ -708,6 +709,14 @@ static int dns_transaction_emit_tcp(DnsTransaction *t) { else fd = dns_scope_socket_tcp(t->scope, AF_UNSPEC, NULL, t->server, dns_transaction_port(t), &sa); + /* Lower timeout in DNS-over-TLS opportunistic mode. In environments where DoT is blocked + * without ICMP response overly long delays when contacting DoT servers are nasty, in + * particular if multiple DNS servers are defined which we try in turn and all are + * blocked. Hence, substantially lower the timeout in that case. */ + if (DNS_SERVER_FEATURE_LEVEL_IS_TLS(t->current_feature_level) && + dns_server_get_dns_over_tls_mode(t->server) == DNS_OVER_TLS_OPPORTUNISTIC) + stream_timeout_usec = DNS_STREAM_OPPORTUNISTIC_TLS_TIMEOUT_USEC; + type = DNS_STREAM_LOOKUP; break; @@ -745,7 +754,7 @@ static int dns_transaction_emit_tcp(DnsTransaction *t) { if (fd < 0) return fd; - r = dns_stream_new(t->scope->manager, &s, type, t->scope->protocol, fd, &sa); + r = dns_stream_new(t->scope->manager, &s, type, t->scope->protocol, fd, &sa, stream_timeout_usec); if (r < 0) return r; diff --git a/src/resolve/resolved-llmnr.c b/src/resolve/resolved-llmnr.c index ce2db7d4b0..32483006b1 100644 --- a/src/resolve/resolved-llmnr.c +++ b/src/resolve/resolved-llmnr.c @@ -313,7 +313,7 @@ static int on_llmnr_stream(sd_event_source *s, int fd, uint32_t revents, void *u return -errno; } - r = dns_stream_new(m, &stream, DNS_STREAM_LLMNR_RECV, DNS_PROTOCOL_LLMNR, cfd, NULL); + r = dns_stream_new(m, &stream, DNS_STREAM_LLMNR_RECV, DNS_PROTOCOL_LLMNR, cfd, NULL, DNS_STREAM_DEFAULT_TIMEOUT_USEC); if (r < 0) { safe_close(cfd); return r; |