diff options
author | Marcin Siodelski <marcin@isc.org> | 2018-01-05 21:43:49 +0100 |
---|---|---|
committer | Marcin Siodelski <marcin@isc.org> | 2018-01-05 21:43:49 +0100 |
commit | 95923b6c408da923e4556a18b32660ac51539711 (patch) | |
tree | 6b0662978d0c21f8b367f17382c01b5c105451da /src/lib/asiolink/tcp_socket.h | |
parent | [5451] Implemented HTTP response parser. (diff) | |
download | kea-95923b6c408da923e4556a18b32660ac51539711.tar.xz kea-95923b6c408da923e4556a18b32660ac51539711.zip |
[5451] Implemented HTTP client.
Diffstat (limited to 'src/lib/asiolink/tcp_socket.h')
-rw-r--r-- | src/lib/asiolink/tcp_socket.h | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/src/lib/asiolink/tcp_socket.h b/src/lib/asiolink/tcp_socket.h index adf74d1f0f..8465c0705e 100644 --- a/src/lib/asiolink/tcp_socket.h +++ b/src/lib/asiolink/tcp_socket.h @@ -1,4 +1,4 @@ -// Copyright (C) 2011-2017 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2011-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 @@ -90,6 +90,47 @@ public: return (false); } + /// \brief Checks if the connection is usable. + /// + /// The connection is usable if the peer has closed it. + /// + /// \return true if the connection is usable. + bool isUsable() const { + // If the socket is open it doesn't mean that it is still usable. The connection + // could have been closed on the other end. We have to check if we can still + // use this socket. + if (socket_.is_open()) { + // Remember the current non blocking setting. + const bool non_blocking_orig = socket_.non_blocking(); + // Set the socket to non blocking mode. We're going to test if the socket + // returns would_block status on the attempt to read from it. + socket_.non_blocking(true); + + boost::system::error_code ec; + char data[2]; + + // Use receive with message peek flag to avoid removing the data awaiting + // to be read. + socket_.receive(boost::asio::buffer(data, sizeof(data)), + boost::asio::socket_base::message_peek, + ec); + + // Revert the original non_blocking flag on the socket. + socket_.non_blocking(non_blocking_orig); + + // If the connection is alive we'd typically get would_block status code. + // If there are any data that haven't been read we may also get success + // status. We're guessing that try_again may also be returned by some + // implementations in some situations. Any other error code indicates a + // problem with the connection so we assume that the connection has been + // closed. + return (!ec || (ec.value() == boost::asio::error::try_again) || + (ec.value() == boost::asio::error::would_block)); + } + + return (false); + } + /// \brief Open Socket /// /// Opens the TCP socket. This is an asynchronous operation, completion of @@ -227,7 +268,11 @@ TCPSocket<C>::~TCPSocket() template <typename C> void TCPSocket<C>::open(const IOEndpoint* endpoint, C& callback) { - + // If socket is open on this end but has been closed by the peer, + // we need to reconnect. + if (socket_.is_open() && !isUsable()) { + close(); + } // Ignore opens on already-open socket. Don't throw a failure because // of uncertainties as to what precedes whan when using asynchronous I/O. // At also allows us a treat a passed-in socket as a self-managed socket. |