From: Marcin Siodelski Date: Wed, 13 Jun 2018 19:44:25 +0000 (+0200) Subject: [5649] ClientConnection timeout is delayed when transaction progresses. X-Git-Tag: Kea-1.4.0~1^2~3^2~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=946c491328f2cc3286ff278d13e13e7fe095e6c2;p=thirdparty%2Fkea.git [5649] ClientConnection timeout is delayed when transaction progresses. --- diff --git a/src/lib/config/client_connection.cc b/src/lib/config/client_connection.cc index e140568443..9222937909 100644 --- a/src/lib/config/client_connection.cc +++ b/src/lib/config/client_connection.cc @@ -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 diff --git a/src/lib/config/client_connection.h b/src/lib/config/client_connection.h index e2b8f805ea..6321f34774 100644 --- a/src/lib/config/client_connection.h +++ b/src/lib/config/client_connection.h @@ -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