From cc514ea58727ba22576eb567acb2a70ba01b58ec Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Thu, 31 Jul 2014 17:35:49 +0200 Subject: [PATCH] Check if connection to cynara is valid Change-Id: I1a406ce6aa092cc75f452493ec22996e675a57ea --- src/client/logic/Logic.cpp | 9 +++++---- src/client/logic/Logic.h | 3 +++ src/common/sockets/Socket.cpp | 26 +++++++++++++++++++++++++- src/common/sockets/Socket.h | 5 +++++ src/common/sockets/SocketClient.cpp | 6 +++++- src/common/sockets/SocketClient.h | 2 ++ 6 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/client/logic/Logic.cpp b/src/client/logic/Logic.cpp index b3492ff..dbdcf36 100644 --- a/src/client/logic/Logic.cpp +++ b/src/client/logic/Logic.cpp @@ -38,10 +38,8 @@ namespace Cynara { const std::string clientSocketPath("/run/cynara/cynara.socket"); Logic::Logic() { - m_cache = std::make_shared( - std::make_shared( - std::make_shared(clientSocketPath, - std::make_shared()))); + m_socket = std::make_shared(clientSocketPath, std::make_shared()); + m_cache = std::make_shared(std::make_shared(m_socket)); auto naiveInterpreter = std::make_shared(); m_cache->registerPlugin(PredefinedPolicyType::ALLOW, naiveInterpreter); m_cache->registerPlugin(PredefinedPolicyType::DENY, naiveInterpreter); @@ -53,6 +51,9 @@ int Logic::check(const std::string &client, const std::string &session, const st { PolicyKey key(client, user, privilege); + if (!m_socket->isConnected()) + onDisconnected(); + auto ret = m_cache->get(session, key); if (ret == CYNARA_API_SERVICE_NOT_AVAILABLE) onDisconnected(); diff --git a/src/client/logic/Logic.h b/src/client/logic/Logic.h index 34ec54c..e9f2c23 100644 --- a/src/client/logic/Logic.h +++ b/src/client/logic/Logic.h @@ -25,6 +25,8 @@ #include +#include + #include #include @@ -33,6 +35,7 @@ namespace Cynara { class Logic : public ApiInterface { private: PluginCachePtr m_cache; + SocketClientPtr m_socket; void onDisconnected(void); diff --git a/src/common/sockets/Socket.cpp b/src/common/sockets/Socket.cpp index e666262..c61134a 100644 --- a/src/common/sockets/Socket.cpp +++ b/src/common/sockets/Socket.cpp @@ -203,7 +203,7 @@ bool Socket::sendToServer(BinaryQueue &queue) { return true; } -bool Socket::receiveFromServer(BinaryQueue &queue) +bool Socket::waitAndReceiveFromServer(BinaryQueue &queue) { if (!waitForSocket(POLLIN)) { LOGE("Error in poll(POLLIN)"); @@ -228,4 +228,28 @@ bool Socket::receiveFromServer(BinaryQueue &queue) return true; } +bool Socket::receiveFromServer(BinaryQueue &queue) +{ + RawBuffer readBuffer(BUFSIZ); + ssize_t size = TEMP_FAILURE_RETRY(read(m_sock, readBuffer.data(), BUFSIZ)); + + if (size == -1) { + int err = errno; + if (err == EAGAIN) { + LOGD("is connected, but no data available"); + return true; + } + LOGE("'read' function error [%d] : <%s>", err, strerror(err)); + throw UnexpectedErrorException(err, strerror(err)); + } + + if (size == 0) { + LOGW("read return 0 / Connection closed by server."); + return false; + } + queue.appendCopy(readBuffer.data(), size); + + return true; +} + } // namespace Cynara diff --git a/src/common/sockets/Socket.h b/src/common/sockets/Socket.h index 7ea8c61..2754142 100644 --- a/src/common/sockets/Socket.h +++ b/src/common/sockets/Socket.h @@ -71,6 +71,11 @@ public: //returns false if connection was lost //throws ServerConnectionErrorException if cannot connect server (or timeout) //throws other exceptions in critical situations + bool waitAndReceiveFromServer(BinaryQueue &queue); + + //returns true if data was successfully read from server + //returns false if connection was lost + //throws other exceptions in critical situations bool receiveFromServer(BinaryQueue &queue); }; diff --git a/src/common/sockets/SocketClient.cpp b/src/common/sockets/SocketClient.cpp index 6eff9f5..d9de1f8 100644 --- a/src/common/sockets/SocketClient.cpp +++ b/src/common/sockets/SocketClient.cpp @@ -52,7 +52,7 @@ ResponsePtr SocketClient::askCynaraServer(RequestPtr request) { // receive response from cynara while (true) { - if (!m_socket.receiveFromServer(m_readQueue)) { + if (!m_socket.waitAndReceiveFromServer(m_readQueue)) { LOGW("Error receiving response from Cynara. Service not available."); return nullptr; } @@ -63,4 +63,8 @@ ResponsePtr SocketClient::askCynaraServer(RequestPtr request) { } } +bool SocketClient::isConnected(void) { + return m_socket.isConnected() && m_socket.receiveFromServer(m_readQueue); +} + } // namespace Cynara diff --git a/src/common/sockets/SocketClient.h b/src/common/sockets/SocketClient.h index 04f0436..fae5ba3 100644 --- a/src/common/sockets/SocketClient.h +++ b/src/common/sockets/SocketClient.h @@ -51,6 +51,8 @@ public: //returns pointer to response // or nullptr when connection to cynara service is lost ResponsePtr askCynaraServer(RequestPtr request); + + bool isConnected(void); }; } // namespace Cynara -- 2.7.4