const boost::system::error_code& ec,
size_t length);
+ /// @brief Disables read and write operations on the socket.
+ void shutdown();
+
/// @brief Closes the socket.
void close();
remote_handler(ec, length);
}
+void
+UnixDomainSocketImpl::shutdown() {
+ boost::system::error_code ec;
+ static_cast<void>(socket_.shutdown(stream_protocol::socket::shutdown_both, ec));
+ if (ec) {
+ isc_throw(UnixDomainSocketError, ec.message());
+ }
+}
+
void
UnixDomainSocketImpl::close() {
- static_cast<void>(socket_.close());
+ boost::system::error_code ec;
+ static_cast<void>(socket_.close(ec));
+ if (ec) {
+ isc_throw(UnixDomainSocketError, ec.message());
+ }
}
UnixDomainSocket::UnixDomainSocket(IOService& io_service)
impl_->asyncReceive(data, length, handler);
}
+void
+UnixDomainSocket::shutdown() {
+ impl_->shutdown();
+}
+
void
UnixDomainSocket::close() {
impl_->close();
/// error is signalled.
void asyncReceive(void* data, const size_t length, const Handler& handler);
+ /// @brief Disables read and write operations on the socket.
+ ///
+ /// @throw UnixDomainSocketError if an error occurs during shutdown.
+ void shutdown();
+
/// @brief Closes the socket.
+ ///
+ /// @throw UnixDomainSocketError if an error occurs during closure.
void close();
/// @brief Returns reference to the underlying ASIO socket.
}
}
+ /// @brief Gracefully terminates current connection.
+ ///
+ /// This method should be called prior to closing the socket to initiate
+ /// graceful shutdown.
+ void terminate();
+
/// @brief Start asynchronous read over the unix domain socket.
///
/// This method doesn't block. Once the transmission is received over the
};
+void
+Connection::terminate() {
+ try {
+ socket_->shutdown();
+
+ } catch (const std::exception& ex) {
+ LOG_ERROR(command_logger, COMMAND_SOCKET_CONNECTION_SHUTDOWN_FAIL)
+ .arg(ex.what());
+ }
+}
void
Connection::receiveHandler(const boost::system::error_code& ec,
doSend();
return;
}
+
+ // Gracefully shutdown the connection and close the socket if
+ // we have sent the whole response.
+ terminate();
}
// All data sent or an error has occurred. Close the connection.
void
Connection::timeoutHandler() {
+ LOG_INFO(command_logger, COMMAND_SOCKET_CONNECTION_TIMEOUT)
+ .arg(socket_->getNative());
+
ConstElementPtr rsp = createAnswer(CONTROL_RESULT_ERROR, "Connection over"
" control channel timed out");
response_ = rsp->str();
This is an informational message that a new incoming command connection was
detected and a dedicated socket was opened for that connection.
+% COMMAND_SOCKET_CONNECTION_SHUTDOWN_FAIL Encountered error %1 while trying to gracefully shutdown socket
+This message indicates an error while trying to gracefully shutdown command
+connection. The type of the error is included in the message.
+
+% COMMAND_SOCKET_CONNECTION_TIMEOUT Timeout occurred for connection over socket %1
+This is an informational message that indicates that the timeout has
+occurred for one of the command channel connections. The response
+sent by the server indicates a timeout and is then closed.
+
% COMMAND_SOCKET_READ Received %1 bytes over command socket %2
This debug message indicates that specified number of bytes was received
over command socket identified by specified file descriptor.