]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: when we get a TCP connection failure, try again
authorLennart Poettering <lennart@poettering.net>
Fri, 8 Jan 2016 01:33:54 +0000 (02:33 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 11 Jan 2016 18:39:59 +0000 (19:39 +0100)
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.

src/basic/fd-util.h
src/resolve/resolved-bus.c
src/resolve/resolved-dns-transaction.c
src/resolve/resolved-dns-transaction.h

index 5ce1592eeb414afaf24caee3b48e104006bb18e5..973413ff42fd029f04817c9c8a47420725d4ceaa 100644 (file)
@@ -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)
index 00095463dddeda9b4d323e5fec9d132b4f15ba6e..d7295ca39cbc2f518eca130c389a3c7708d71eae 100644 (file)
@@ -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");
 
index 78fbb383092aa62c2fae21c06ee49cfbe3880910..e6e7aeec63513af93951967da694cd80cc5af448 100644 (file)
@@ -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",
index ede33f954705a7c800df593fff6413b34981c021..0df7d017377b4387e8d33972eb54a6aa946347cd 100644 (file)
@@ -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,