]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: restart stream timeout whenever we managed to read or write something
authorLennart Poettering <lennart@poettering.net>
Mon, 21 Jan 2019 18:29:51 +0000 (19:29 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 15 Feb 2019 16:13:58 +0000 (17:13 +0100)
Previously we'd start the timeout once when we allocated the stream.
However, we'd now like to emphasize long-running connections hence let's
rework the timeout logic, and restart it whenever we see action ont the
stream. Thus, idle streams are eventually closed down, but those where
we read or write from are not.

src/resolve/resolved-dns-stream.c

index ebafaa529c72606cb3a7fc9267aab53bedb73d9b..ecc7e9fa091516b8bbf0fced5877666d8ab7501a 100644 (file)
@@ -281,6 +281,7 @@ static int on_stream_timeout(sd_event_source *es, usec_t usec, void *userdata) {
 
 static int on_stream_io(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
         _cleanup_(dns_stream_unrefp) DnsStream *s = dns_stream_ref(userdata); /* Protect stream while we process it */
+        bool progressed = false;
         int r;
 
         assert(s);
@@ -324,8 +325,10 @@ static int on_stream_io(sd_event_source *es, int fd, uint32_t revents, void *use
                 if (ss < 0) {
                         if (!IN_SET(-ss, EINTR, EAGAIN))
                                 return dns_stream_complete(s, -ss);
-                } else
+                } else {
+                        progressed = true;
                         s->n_written += ss;
+                }
 
                 /* Are we done? If so, disable the event source for EPOLLOUT */
                 if (s->n_written >= sizeof(s->write_size) + s->write_packet->size) {
@@ -348,8 +351,10 @@ static int on_stream_io(sd_event_source *es, int fd, uint32_t revents, void *use
                                         return dns_stream_complete(s, -ss);
                         } else if (ss == 0)
                                 return dns_stream_complete(s, ECONNRESET);
-                        else
+                        else {
+                                progressed = true;
                                 s->n_read += ss;
+                        }
                 }
 
                 if (s->n_read >= sizeof(s->read_size)) {
@@ -424,6 +429,13 @@ static int on_stream_io(sd_event_source *es, int fd, uint32_t revents, void *use
             (s->read_packet && s->n_read >= sizeof(s->read_size) + s->read_packet->size))
                 return dns_stream_complete(s, 0);
 
+        /* If we did something, let's restart the timeout event source */
+        if (progressed && s->timeout_event_source) {
+                r = sd_event_source_set_time(s->timeout_event_source, now(clock_boottime_or_monotonic()) + DNS_STREAM_TIMEOUT_USEC);
+                if (r < 0)
+                        log_warning_errno(errno, "Couldn't restart TCP connection timeout, ignoring: %m");
+        }
+
         return 0;
 }