From eace8a517077c39a37bfbcaf269d72ce190eff23 Mon Sep 17 00:00:00 2001 From: Francis Dupont Date: Thu, 29 Mar 2018 15:41:28 +0200 Subject: [PATCH] [5374] Updated asiolink --- src/lib/asiolink/io_acceptor.h | 4 ++ src/lib/asiolink/io_address.h | 21 ++++++++--- src/lib/asiolink/io_asio_socket.h | 3 +- src/lib/asiolink/io_service.h | 5 +++ src/lib/asiolink/tcp_socket.h | 54 ++++++++++++++++++++++++++- src/lib/asiolink/tests/io_service_unittest.cc | 2 + src/lib/asiolink/tests/run_unittests.cc | 2 + src/lib/asiolink/udp_socket.h | 4 ++ src/lib/asiolink/unix_domain_socket.cc | 4 ++ 9 files changed, 90 insertions(+), 9 deletions(-) diff --git a/src/lib/asiolink/io_acceptor.h b/src/lib/asiolink/io_acceptor.h index c493d3427e..913a3280b2 100644 --- a/src/lib/asiolink/io_acceptor.h +++ b/src/lib/asiolink/io_acceptor.h @@ -47,7 +47,11 @@ class IOAcceptor : public IOSocket { /// @brief Returns file descriptor of the underlying socket. virtual int getNative() const { +#if BOOST_VERSION < 106600 return (acceptor_->native()); +#else + return (acceptor_->native_handle()); +#endif } /// @brief Opens acceptor socket given the endpoint. diff --git a/src/lib/asiolink/io_address.h b/src/lib/asiolink/io_address.h index 5747cb9291..42f09d7a9f 100644 --- a/src/lib/asiolink/io_address.h +++ b/src/lib/asiolink/io_address.h @@ -1,4 +1,4 @@ -// Copyright (C) 2010-2017 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2010-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 @@ -23,11 +23,20 @@ namespace isc { namespace asiolink { - /// Defines length of IPv6 address. - const static size_t V6ADDRESS_LEN = 16; + /// Defines length of IPv6 address (in binary format). + static constexpr size_t V6ADDRESS_LEN = 16; - /// Defines length of IPv4 address. - const static size_t V4ADDRESS_LEN = 4; + /// Defines length of IPv4 address (in binary format). + static constexpr size_t V4ADDRESS_LEN = 4; + + /// @brief Maximum size of an IPv4 address represented as a text string. 12 + /// digits plus 3 full stops (dots). + static constexpr size_t V4ADDRESS_TEXT_MAX_LEN = 15u; + + /// @brief Maximum size of an IPv6 address represented as a text string. 32 + /// hexadecimal characters written in 8 groups of four, plus 7 colon + /// separators. + static constexpr size_t V6ADDRESS_TEXT_MAX_LEN = 39u; /// \brief The \c IOAddress class represents an IP addresses (version /// agnostic) @@ -136,7 +145,7 @@ class IOAddress { /// \brief Creates an address from over wire data. /// - /// \param family AF_NET for IPv4 or AF_NET6 for IPv6. + /// \param family AF_INET for IPv4 or AF_INET6 for IPv6. /// \param data pointer to first char of data /// /// \return Created IOAddress object diff --git a/src/lib/asiolink/io_asio_socket.h b/src/lib/asiolink/io_asio_socket.h index cdb4074db2..49f5041db4 100644 --- a/src/lib/asiolink/io_asio_socket.h +++ b/src/lib/asiolink/io_asio_socket.h @@ -16,13 +16,14 @@ #include #include -#include #include #include #include +#include + namespace isc { namespace asiolink { diff --git a/src/lib/asiolink/io_service.h b/src/lib/asiolink/io_service.h index e9e402d114..e0832b2c04 100644 --- a/src/lib/asiolink/io_service.h +++ b/src/lib/asiolink/io_service.h @@ -11,7 +11,12 @@ namespace boost { namespace asio { +#if BOOST_VERSION < 106600 class io_service; +#else + class io_context; + typedef io_context io_service; +#endif } } diff --git a/src/lib/asiolink/tcp_socket.h b/src/lib/asiolink/tcp_socket.h index adf74d1f0f..f1297e0630 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 @@ -75,7 +75,11 @@ class TCPSocket : public IOAsioSocket { /// \brief Return file descriptor of underlying socket virtual int getNative() const { +#if BOOST_VERSION < 106600 return (socket_.native()); +#else + return (socket_.native_handle()); +#endif } /// \brief Return protocol of socket @@ -90,6 +94,48 @@ class TCPSocket : public IOAsioSocket { return (false); } + /// \brief Checks if the connection is usable. + /// + /// The connection is usable if the socket is open and the peer has not + /// closed its connection. + /// + /// \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 +273,11 @@ TCPSocket::~TCPSocket() template void TCPSocket::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. diff --git a/src/lib/asiolink/tests/io_service_unittest.cc b/src/lib/asiolink/tests/io_service_unittest.cc index 70887c3d24..b1c33956be 100644 --- a/src/lib/asiolink/tests/io_service_unittest.cc +++ b/src/lib/asiolink/tests/io_service_unittest.cc @@ -4,6 +4,8 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. +#include + #include #include diff --git a/src/lib/asiolink/tests/run_unittests.cc b/src/lib/asiolink/tests/run_unittests.cc index 7044863677..395dcd1d6e 100644 --- a/src/lib/asiolink/tests/run_unittests.cc +++ b/src/lib/asiolink/tests/run_unittests.cc @@ -4,6 +4,8 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. +#include + #include #include #include diff --git a/src/lib/asiolink/udp_socket.h b/src/lib/asiolink/udp_socket.h index 07ba44743e..5b040cfe1b 100644 --- a/src/lib/asiolink/udp_socket.h +++ b/src/lib/asiolink/udp_socket.h @@ -61,7 +61,11 @@ class UDPSocket : public IOAsioSocket { /// \brief Return file descriptor of underlying socket virtual int getNative() const { +#if BOOST_VERSION < 106600 return (socket_.native()); +#else + return (socket_.native_handle()); +#endif } /// \brief Return protocol of socket diff --git a/src/lib/asiolink/unix_domain_socket.cc b/src/lib/asiolink/unix_domain_socket.cc index f17ec2e8f7..d1ad9ec30c 100644 --- a/src/lib/asiolink/unix_domain_socket.cc +++ b/src/lib/asiolink/unix_domain_socket.cc @@ -287,7 +287,11 @@ UnixDomainSocket::UnixDomainSocket(IOService& io_service) int UnixDomainSocket::getNative() const { +#if BOOST_VERSION < 106600 return (impl_->socket_.native()); +#else + return (impl_->socket_.native_handle()); +#endif } int