summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-01-08 02:33:54 +0100
committerLennart Poettering <lennart@poettering.net>2016-01-11 19:39:59 +0100
commita1a3f73a57da25dbd158ea71607b7d740b101f49 (patch)
treebf1939c4928ca1d1af3e6b6449826de7f60131a8
parent6a1a5eec43892dee3ff6e208bceb1931c25c782e (diff)
resolved: when we get a TCP connection failure, try again
Previously, when we couldn't connect to a DNS server via TCP we'd abort the whole transaction using a "connection-failure" state. This change removes that, and counts failed connections as "lost packet" events, so that we switch back to the UDP protocol again.
-rw-r--r--src/basic/fd-util.h3
-rw-r--r--src/resolve/resolved-bus.c3
-rw-r--r--src/resolve/resolved-dns-transaction.c12
-rw-r--r--src/resolve/resolved-dns-transaction.h1
4 files changed, 11 insertions, 8 deletions
diff --git a/src/basic/fd-util.h b/src/basic/fd-util.h
index 5ce1592eeb..973413ff42 100644
--- a/src/basic/fd-util.h
+++ b/src/basic/fd-util.h
@@ -73,3 +73,6 @@ int same_fd(int a, int b);
void cmsg_close_all(struct msghdr *mh);
bool fdname_is_valid(const char *s);
+
+#define ERRNO_IS_DISCONNECT(r) \
+ IN_SET(r, ENOTCONN, ECONNRESET, ECONNREFUSED, ECONNABORTED, EPIPE)
diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c
index 00095463dd..d7295ca39c 100644
--- a/src/resolve/resolved-bus.c
+++ b/src/resolve/resolved-bus.c
@@ -57,9 +57,6 @@ static int reply_query_state(DnsQuery *q) {
case DNS_TRANSACTION_RESOURCES:
return sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_RESOURCES, "Not enough resources");
- case DNS_TRANSACTION_CONNECTION_FAILURE:
- return sd_bus_reply_method_errorf(q->request, BUS_ERROR_CONNECTION_FAILURE, "DNS server connection failure");
-
case DNS_TRANSACTION_ABORTED:
return sd_bus_reply_method_errorf(q->request, BUS_ERROR_ABORTED, "Query aborted");
diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c
index 78fbb38309..e6e7aeec63 100644
--- a/src/resolve/resolved-dns-transaction.c
+++ b/src/resolve/resolved-dns-transaction.c
@@ -365,11 +365,16 @@ static int on_stream_complete(DnsStream *s, int error) {
t->stream = dns_stream_free(t->stream);
- if (IN_SET(error, ENOTCONN, ECONNRESET, ECONNREFUSED, ECONNABORTED, EPIPE)) {
- dns_transaction_complete(t, DNS_TRANSACTION_CONNECTION_FAILURE);
+ if (ERRNO_IS_DISCONNECT(error)) {
+ usec_t usec;
+
+ log_debug_errno(error, "Connection failure for DNS TCP stream, treating as lost packet: %m");
+ assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &usec) >= 0);
+ dns_server_packet_lost(t->server, t->current_features, usec - t->start_usec);
+
+ dns_transaction_retry(t);
return 0;
}
-
if (error != 0) {
dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
return 0;
@@ -2727,7 +2732,6 @@ static const char* const dns_transaction_state_table[_DNS_TRANSACTION_STATE_MAX]
[DNS_TRANSACTION_ATTEMPTS_MAX_REACHED] = "attempts-max-reached",
[DNS_TRANSACTION_INVALID_REPLY] = "invalid-reply",
[DNS_TRANSACTION_RESOURCES] = "resources",
- [DNS_TRANSACTION_CONNECTION_FAILURE] = "connection-failure",
[DNS_TRANSACTION_ABORTED] = "aborted",
[DNS_TRANSACTION_DNSSEC_FAILED] = "dnssec-failed",
[DNS_TRANSACTION_NO_TRUST_ANCHOR] = "no-trust-anchor",
diff --git a/src/resolve/resolved-dns-transaction.h b/src/resolve/resolved-dns-transaction.h
index ede33f9547..0df7d01737 100644
--- a/src/resolve/resolved-dns-transaction.h
+++ b/src/resolve/resolved-dns-transaction.h
@@ -36,7 +36,6 @@ enum DnsTransactionState {
DNS_TRANSACTION_ATTEMPTS_MAX_REACHED,
DNS_TRANSACTION_INVALID_REPLY,
DNS_TRANSACTION_RESOURCES,
- DNS_TRANSACTION_CONNECTION_FAILURE,
DNS_TRANSACTION_ABORTED,
DNS_TRANSACTION_DNSSEC_FAILED,
DNS_TRANSACTION_NO_TRUST_ANCHOR,