]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[5649] ClientConnection timeout is delayed when transaction progresses.
authorMarcin Siodelski <marcin@isc.org>
Wed, 13 Jun 2018 19:44:25 +0000 (21:44 +0200)
committerMarcin Siodelski <marcin@isc.org>
Wed, 13 Jun 2018 19:44:25 +0000 (21:44 +0200)
src/lib/config/client_connection.cc
src/lib/config/client_connection.h

index e140568443cc9b7652dd83ae2409dc9ccd22395f..92229379094c95a13a3016e61414f13514029aa0 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2017-2018 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -29,6 +29,13 @@ public:
     /// @param io_service Reference to the IO service.
     explicit ClientConnectionImpl(IOService& io_service);
 
+    /// @brief This method schedules timer or reschedules existing timer.
+    ///
+    /// @param handler Pointer to the user supplied callback function which
+    /// should be invoked when transaction completes or when an error has
+    /// occurred during the transaction.
+    void scheduleTimer(ClientConnection::Handler handler);
+
     /// @brief Starts asynchronous transaction with a remote endpoint.
     ///
     /// See @ref ClientConnection::start documentation for the details.
@@ -103,10 +110,23 @@ private:
 
     /// @brief Instance of the interval timer protecting against timeouts.
     IntervalTimer timer_;
+
+    /// @brief Timeout value used for the timer.
+    long timeout_;
 };
 
 ClientConnectionImpl::ClientConnectionImpl(IOService& io_service)
-    : socket_(io_service), feed_(), current_command_(), timer_(io_service) {
+    : socket_(io_service), feed_(), current_command_(), timer_(io_service),
+      timeout_(0) {
+}
+
+void
+ClientConnectionImpl::scheduleTimer(ClientConnection::Handler handler) {
+    if (timeout_ > 0) {
+        timer_.setup(boost::bind(&ClientConnectionImpl::timeoutCallback,
+                                 this, handler),
+                     timeout_, IntervalTimer::ONE_SHOT);
+    }
 }
 
 void
@@ -115,9 +135,8 @@ ClientConnectionImpl::start(const ClientConnection::SocketPath& socket_path,
                             ClientConnection::Handler handler,
                             const ClientConnection::Timeout& timeout) {
     // Start the timer protecting against timeouts.
-    timer_.setup(boost::bind(&ClientConnectionImpl::timeoutCallback,
-                             this, handler),
-                 timeout.timeout_, IntervalTimer::ONE_SHOT);
+    timeout_ = timeout.timeout_;
+    scheduleTimer(handler);
 
     // Store the command in the class member to make sure it is valid
     // the entire time.
@@ -162,6 +181,9 @@ ClientConnectionImpl::doSend(const void* buffer, const size_t length,
             terminate(ec, handler);
 
         } else {
+            // Sending is in progress, so push back the timeout.
+            scheduleTimer(handler);
+
             // If the number of bytes we have managed to send so far is
             // lower than the amount of data we're trying to send, we
             // have to schedule another send to deliver the rest of
@@ -193,6 +215,9 @@ ClientConnectionImpl::doReceive(ClientConnection::Handler handler) {
             terminate(ec, handler);
 
         } else {
+            // Receiving is in progress, so push back the timeout.
+            scheduleTimer(handler);
+
             std::string x(&read_buf_[0], length);
             // Lazy initialization of the JSONFeed. The feed will be "parsing"
             // received JSON stream and will detect when the whole response
index e2b8f805ea1cba87bffd379a1a896f8252d0196c..6321f34774bf71ab35f65e88953b97e3f5f967aa 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2017-2018 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -117,9 +117,11 @@ public:
     /// sent to the remote endpoint. When the entire command has been sent,
     /// the response is read asynchronously, possibly in multiple chunks.
     ///
-    /// The timeout is specified for the entire transaction in milliseconds.
-    /// If the transaction takes longer than the timeout value the connection
-    /// is closed and the callback is called with the error code of
+    /// The timeout is specified in milliseconds. The corresponding timer
+    /// measures the connection idle time. If the transaction is progressing,
+    /// the timer is updated accordingly. If the connection idle time is
+    /// longer than the timeout value the connection is closed and the
+    /// callback is called with the error code of
     /// @c boost::asio::error::timed_out.
     ///
     /// In other cases, the callback is called with the error code returned