Refactor dcm-deamon code 52/235452/10
authorDariusz Michaluk <d.michaluk@samsung.com>
Thu, 4 Jun 2020 12:39:07 +0000 (14:39 +0200)
committerDariusz Michaluk <d.michaluk@samsung.com>
Mon, 6 Jul 2020 09:59:39 +0000 (11:59 +0200)
- remove service_adapter class
- code formatting changes
- cleanup soresolver, dcm_session, dcm_server classes

Change-Id: I3a464c524ce6a3e17f0769f12c7a9abdd66e119d

12 files changed:
src/dcm-daemon/CMakeLists.txt
src/dcm-daemon/dcm-backend-api.h
src/dcm-daemon/dcm_server.cpp [moved from src/dcm-daemon/dcmserver.cpp with 61% similarity]
src/dcm-daemon/dcm_server.h [moved from src/dcm-daemon/dcmserver.h with 73% similarity]
src/dcm-daemon/dcm_session.cpp [moved from src/dcm-daemon/dcmsession.cpp with 69% similarity]
src/dcm-daemon/dcm_session.h [moved from src/dcm-daemon/dcmsession.h with 78% similarity]
src/dcm-daemon/exception_translator.h [deleted file]
src/dcm-daemon/main.cpp
src/dcm-daemon/serviceadapter.cpp [deleted file]
src/dcm-daemon/serviceadapter.h [deleted file]
src/dcm-daemon/soresolver.cpp
src/dcm-daemon/soresolver.h

index cc19760..aadb2be 100644 (file)
@@ -40,9 +40,8 @@ PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ../dcm-client/dcm_support.proto)
 SET(TARGET_DAEMON "device-certificate-managerd")
 ADD_EXECUTABLE(${TARGET_DAEMON}
        main.cpp
-       dcmserver.cpp
-       dcmsession.cpp
-       serviceadapter.cpp
+       dcm_server.cpp
+       dcm_session.cpp
        ../shared/protobuf_asio.cpp
        ../shared/log.cpp
        soresolver.cpp
index 208ff61..7ae2ce0 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************
  *
- * Copyright 2019 Samsung Electronics All Rights Reserved.
+ * Copyright 2019 - 2020 Samsung Electronics All Rights Reserved.
  *
  * Author: Pawel Kowalski <p.kowalski2@partner.samsung.com>
  *
@@ -44,7 +44,7 @@ void dcm_backend_free_key_context(dcm_backend_context& ctx);
 
 API_DCM_BACKEND_EXPORT
 int dcm_backend_request_certificate_chain(dcm_backend_context& ctx,
-                                          std::string& mutable_chain);
+                                          std::string& chain);
 
 API_DCM_BACKEND_EXPORT
 int dcm_backend_sign_crypto_data(dcm_backend_context& ctx,
similarity index 61%
rename from src/dcm-daemon/dcmserver.cpp
rename to src/dcm-daemon/dcm_server.cpp
index 76a3dbb..efb0f5c 100644 (file)
  *
  ******************************************************************/
 
-#include "dcmserver.h"
-#include "dcmsession.h"
+#include <cynara-client.h>
+#include <systemd/sd-daemon.h>
+
+#include "dcm_server.h"
+#include "dcm_session.h"
 #include "log.h"
 
-dcm_server::dcm_server(boost::asio::io_service& io_service, boost::asio::local::stream_protocol::acceptor&& acceptor, std::string lib_backend) :
-       fService(io_service),
-       fTimer(io_service),
-       fAcceptor(std::move(acceptor)),
-       fSoResolver(std::make_shared<so_resolver>(lib_backend))
+dcm_server::dcm_server(boost::asio::io_service& io_service,
+       boost::asio::local::stream_protocol::acceptor&& acceptor) :
+               fService(io_service),
+               fTimer(io_service),
+               fAcceptor(std::move(acceptor)),
+               fSoResolver(std::make_shared<so_resolver>())
 {
        LOGD("Construct server object");
+
+       cynara_configuration* cynara_conf = nullptr;
+       int error = cynara_configuration_create(&cynara_conf);
+       if(error != CYNARA_API_SUCCESS) {
+               LOGE("Can't initialize Cynara configuration: " << error);
+               throw std::runtime_error("Can't initialize Cynara configuration");
+       }
+
+       error = cynara_initialize(&fCynaraInstance, cynara_conf);
+       cynara_configuration_destroy(cynara_conf);
+       if(error != CYNARA_API_SUCCESS) {
+               LOGE("Can't initialize Cynara instance: " << error);
+               throw std::runtime_error("Can't initialize Cynara instance");
+       }
 }
 
 dcm_server::~dcm_server()
 {
+       cynara_finish(fCynaraInstance);
        LOGD("Destroy server object");
 }
 
 void dcm_server::start()
 {
+       LOGD("Start server");
+       sd_listen_fds(1);
+       sd_notify(0, "READY=1");
        do_accept();
 }
 
@@ -47,7 +69,8 @@ void dcm_server::do_accept()
        std::shared_ptr<dcm_session> session;
 
        try {
-               session = std::make_shared<dcm_session>(fService, fTimer, shared_from_this(), fSoResolver);
+               session = std::make_shared<dcm_session>(fService, fTimer, shared_from_this(),
+                       fSoResolver, fCynaraInstance, fSessionCounter);
        } catch(std::bad_alloc& ex) {
                LOGE("Out of memory when trying to allocate new session");
                return;
similarity index 73%
rename from src/dcm-daemon/dcmserver.h
rename to src/dcm-daemon/dcm_server.h
index c05dc5b..199f066 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************
  *
- * Copyright 2017 - 2019 Samsung Electronics All Rights Reserved.
+ * Copyright 2017 - 2020 Samsung Electronics All Rights Reserved.
  *
  * Author: Jaroslaw Pelczar <j.pelczar@samsung.com>
  *
  *
  ******************************************************************/
 
-#ifndef DCM_DAEMON_DCMSERVER_H_
-#define DCM_DAEMON_DCMSERVER_H_
+#ifndef DCM_DAEMON_DCM_SERVER_H_
+#define DCM_DAEMON_DCM_SERVER_H_
+
+#include <memory>
 
 #include <boost/asio.hpp>
 #include <boost/noncopyable.hpp>
-#include <mutex>
-#include <memory>
+#include <cynara-client.h>
+
 #include "soresolver.h"
 
 class dcm_server final : public boost::noncopyable, public std::enable_shared_from_this<dcm_server> {
 public:
-       dcm_server(boost::asio::io_service& io_service, boost::asio::local::stream_protocol::acceptor&& acceptor, std::string lib_backend);
+       dcm_server(boost::asio::io_service& io_service,
+               boost::asio::local::stream_protocol::acceptor&& acceptor);
        ~dcm_server();
        void start();
 
@@ -40,8 +43,9 @@ private:
        boost::asio::io_service&                                                fService;
        boost::asio::deadline_timer                                             fTimer;
        boost::asio::local::stream_protocol::acceptor   fAcceptor;
-       std::mutex                                                                              fLock;
-       std::shared_ptr<so_resolver> fSoResolver;
+       std::shared_ptr<so_resolver>                                    fSoResolver;
+       cynara*                                                                                 fCynaraInstance;
+       unsigned int                                                                    fSessionCounter = 0;
 };
 
-#endif /* DCM_DAEMON_DCMSERVER_H_ */
+#endif /* DCM_DAEMON_DCM_SERVER_H_ */
similarity index 69%
rename from src/dcm-daemon/dcmsession.cpp
rename to src/dcm-daemon/dcm_session.cpp
index a234f94..a430620 100644 (file)
 
 #include <iostream>
 #include <cassert>
-#include <map>
-#include <mutex>
 
 #include <cynara-client.h>
 #include <cynara-creds-socket.h>
 #include <cynara-session.h>
 
-#include "dcmsession.h"
+#include "dcm_session.h"
+#include "dcm_server.h"
 #include "log.h"
-#include "exception_translator.h"
-#include "dcmserver.h"
-
-extern cynara * gGlobalCynaraInstance;
-
-static inline std::string cynara_error_to_string(int error) {
-       char buffer[256];
-       int ret = cynara_strerror(error, buffer, sizeof(buffer));
-       if(ret == CYNARA_API_SUCCESS)
-               return std::string(buffer);
-       return std::string("Can't translate error");
-}
-
-unsigned int globalSessionCounter = 0;
 
 dcm_session::dcm_session(boost::asio::io_service& io_service,
-               boost::asio::deadline_timer& timer,
-               const std::shared_ptr<dcm_server>& server,
-               std::shared_ptr<so_resolver> soResolver) :
-       fService(io_service),
-       fTimer(timer),
-       fSocket(io_service),
-       fServer(server),
-       fSoResolver(soResolver)
+       boost::asio::deadline_timer& timer,
+       const std::shared_ptr<dcm_server>& server,
+       std::shared_ptr<so_resolver> soResolver,
+       cynara* cynaraInstance,
+       unsigned int& sessionCounter) :
+               fService(io_service),
+               fTimer(timer),
+               fSocket(io_service),
+               fServer(server),
+               fSoResolver(soResolver),
+               fCynaraInstance(cynaraInstance),
+               fSessionCounter(sessionCounter)
 {
        LOGD("Create new session object " << this);
-       globalSessionCounter++;
+       fSessionCounter++;
 }
 
 dcm_session::~dcm_session()
@@ -63,73 +52,6 @@ dcm_session::~dcm_session()
        LOGD("Destroy session object " << this);
 }
 
-struct string_free_deleter {
-       void operator()(char * p) const {
-               free(p);
-       }
-};
-
-bool dcm_session::verify_privileges(int handle)
-{
-       int ret = 0;
-       char * tmp_str;
-       pid_t pid = 0;
-
-       std::unique_ptr<char, string_free_deleter> user;
-       std::unique_ptr<char, string_free_deleter> client;
-       std::unique_ptr<char, string_free_deleter> client_session;
-
-       /* Get user info */
-       tmp_str = nullptr;
-       ret = cynara_creds_socket_get_user(handle, USER_METHOD_DEFAULT, &tmp_str);
-       if(ret != CYNARA_API_SUCCESS) {
-               LOGE("Can't get user from socket : " << ret << " - " << cynara_error_to_string(ret));
-               return false;
-       }
-       user.reset(tmp_str);
-
-       /* Get client info */
-       tmp_str = nullptr;
-       ret = cynara_creds_socket_get_client(handle, CLIENT_METHOD_DEFAULT, &tmp_str);
-       if(ret != CYNARA_API_SUCCESS) {
-               LOGE("Can't get client from socket : " << ret << " - " << cynara_error_to_string(ret));
-               return false;
-       }
-       client.reset(tmp_str);
-
-
-       /* Get client PID from socket */
-       ret = cynara_creds_socket_get_pid(handle, &pid);
-       if(ret != CYNARA_API_SUCCESS) {
-               LOGE("Can't get PID from socket : " << ret << " - " << cynara_error_to_string(ret));
-               return false;
-       }
-
-       client_session.reset(cynara_session_from_pid(pid));
-       if(!client_session) {
-               LOGE("Can't get session identifier from PID");
-               return false;
-       }
-
-       LOGD("Got new session from " << pid << " with user " << user.get() <<
-               ", client ID " << client.get() << " and session ID " << client_session.get());
-
-       ret = cynara_check(gGlobalCynaraInstance,
-                       client.get(),
-                       client_session.get(),
-                       user.get(),
-                       "http://tizen.org/privilege/devicecertificate");
-
-       if(ret != CYNARA_API_ACCESS_ALLOWED) {
-               LOGE("Application access denied for " << pid << " - " << cynara_error_to_string(ret));
-               return false;
-       }
-
-       LOGD("Access granted for " << pid);
-
-       return true;
-}
-
 void dcm_session::start()
 {
        int handle = fSocket.native_handle();
@@ -146,10 +68,10 @@ void dcm_session::start()
 
 void dcm_session::start_timer()
 {
-       globalSessionCounter--;
-       LOGD("Number of active connections: " << globalSessionCounter);
+       fSessionCounter--;
+       LOGD("Number of active connections: " << fSessionCounter);
 
-       if(globalSessionCounter == 0) {
+       if(fSessionCounter == 0) {
                LOGD("No active connections, server will be closed after few seconds");
                fTimer.expires_from_now(boost::posix_time::seconds(10));
                /* operation_aborted error is returned whenever we cancel the timer or we reset the timer using expires_from_now function */
@@ -164,8 +86,8 @@ void dcm_session::start_timer()
 
 void dcm_session::stop_timer()
 {
-       globalSessionCounter++;
-       LOGD("Number of active connections: " << globalSessionCounter);
+       fSessionCounter++;
+       LOGD("Number of active connections: " << fSessionCounter);
 
        fTimer.cancel();
        LOGD("Timer cancelled");
@@ -180,19 +102,19 @@ void dcm_session::do_receive() noexcept
 
                fDeserializer.read_message(fSocket,
                        [self, this](const boost::system::error_code& error, std::size_t bytes_read) {
-                                       if(!error) {
-                                               LOGD("Received " << bytes_read << " bytes from client");
-                                               decode_message();
-                                       } else {
-                                               LOGE("Client disconnected: " << error);
-                                               // Connection object will be released by shared ptr
-                                               start_timer();
-                                       }
+                               if(!error) {
+                                       LOGD("Received " << bytes_read << " bytes from client");
+                                       decode_message();
+                               } else {
+                                       LOGE("Client disconnected: " << error);
+                                       // Connection object will be released by shared ptr
+                                       start_timer();
+                               }
                        });
        } catch(std::exception& ex) {
                LOGE("Caught exception while trying to read message : " << ex.what());
                // Connection object will be released by shared ptr
-       } catch(...) {
+       } catch(...) {
                LOGE("Caught unknown exception while trying to read message");
                // Connection object will be released by shared ptr
        }
@@ -212,19 +134,19 @@ void dcm_session::decode_message() noexcept
 
                switch(requestMessage.request_oneof_case())
                {
-               case RequestMessage::kAssociateContext:
-                       handle_context_association(requestMessage.associate_context());
-                       break;
-               case RequestMessage::kRequestChain:
-                       handle_cert_chain(requestMessage.request_chain());
-                       break;
-               case RequestMessage::kSignData:
-                       handle_sign_request(requestMessage.sign_data());
-                       break;
-               default:
-                       LOGE("Incorrect request message type");
-                       // This will terminate connection
-                       return;
+                       case RequestMessage::kAssociateContext:
+                               handle_context_association(requestMessage.associate_context());
+                               break;
+                       case RequestMessage::kRequestChain:
+                               handle_cert_chain(requestMessage.request_chain());
+                               break;
+                       case RequestMessage::kSignData:
+                               handle_sign_request(requestMessage.sign_data());
+                               break;
+                       default:
+                               LOGE("Incorrect request message type");
+                               // This will terminate connection
+                               return;
                }
        } catch(std::exception& ex) {
                LOGE("Caught exception while parsing message : " << ex.what());
@@ -243,7 +165,7 @@ void dcm_session::reply(const ResponseMessage& resp) noexcept
                fSerializer.encodeMessage(resp);
 
                fSerializer.async_write(fSocket,
-                               [self, this](const boost::system::error_code& error, std::size_t bytes_written)
+                       [self, this](const boost::system::error_code& error, std::size_t bytes_written)
                        {
                                if(!error) {
                                        LOGD("Written " << bytes_written << " to socket");
@@ -262,12 +184,82 @@ void dcm_session::reply(const ResponseMessage& resp) noexcept
        }
 }
 
+struct string_free_deleter {
+       void operator()(char * p) const {
+               free(p);
+       }
+};
+
+static inline std::string cynara_error_to_string(int error) {
+       char buffer[256];
+       int ret = cynara_strerror(error, buffer, sizeof(buffer));
+       if(ret == CYNARA_API_SUCCESS)
+               return std::string(buffer);
+       return std::string("Can't translate error");
+}
+
+bool dcm_session::verify_privileges(int handle)
+{
+       int ret = 0;
+       char* tmp_str;
+       pid_t pid = 0;
+
+       std::unique_ptr<char, string_free_deleter> user;
+       std::unique_ptr<char, string_free_deleter> client;
+       std::unique_ptr<char, string_free_deleter> client_session;
+
+       /* Get user info */
+       tmp_str = nullptr;
+       ret = cynara_creds_socket_get_user(handle, USER_METHOD_DEFAULT, &tmp_str);
+       if(ret != CYNARA_API_SUCCESS) {
+               LOGE("Can't get user from socket : " << ret << " - " << cynara_error_to_string(ret));
+               return false;
+       }
+       user.reset(tmp_str);
+
+       /* Get client info */
+       tmp_str = nullptr;
+       ret = cynara_creds_socket_get_client(handle, CLIENT_METHOD_DEFAULT, &tmp_str);
+       if(ret != CYNARA_API_SUCCESS) {
+               LOGE("Can't get client from socket : " << ret << " - " << cynara_error_to_string(ret));
+               return false;
+       }
+       client.reset(tmp_str);
+
+       /* Get client PID from socket */
+       ret = cynara_creds_socket_get_pid(handle, &pid);
+       if(ret != CYNARA_API_SUCCESS) {
+               LOGE("Can't get PID from socket : " << ret << " - " << cynara_error_to_string(ret));
+               return false;
+       }
+
+       client_session.reset(cynara_session_from_pid(pid));
+       if(!client_session) {
+               LOGE("Can't get session identifier from PID");
+               return false;
+       }
+
+       LOGD("Got new session from " << pid << " with user " << user.get() <<
+               ", client ID " << client.get() << " and session ID " << client_session.get());
+
+       ret = cynara_check(fCynaraInstance, client.get(), client_session.get(), user.get(),
+               "http://tizen.org/privilege/devicecertificate");
+
+       if(ret != CYNARA_API_ACCESS_ALLOWED) {
+               LOGE("Application access denied for " << pid << " - " << cynara_error_to_string(ret));
+               return false;
+       }
+
+       LOGD("Access granted for " << pid);
+       return true;
+}
+
 void dcm_session::handle_context_association(const AssociateKeyContext& message)
 {
        LOGD("Associate context");
 
        ResponseMessage msg;
-       auto * contextResponse = msg.mutable_associate_context();
+       auto* contextResponse = msg.mutable_associate_context();
 
        if(fBackendContext) {
                contextResponse->set_result(EEXIST);
@@ -279,46 +271,37 @@ void dcm_session::handle_context_association(const AssociateKeyContext& message)
                " with usage " << message.usage() << " and key type " << message.key_type());
 
        auto server = fServer.lock();
-
        if(!server) {
                LOGE("Server object gone while handling message");
                return;
        }
 
-       int error = run_with_exception_handler([&]() {
-
-               bool loaded = fSoResolver->ensure_loaded();
-               if (loaded) {
-                       fBackendContext = std::unique_ptr<dcm_backend_context>(new dcm_backend_context);
-
-                       fSoResolver->invoke<void, dcm_backend_context&, const std::string&>(
-                               "dcm_backend_create_key_context",
-                               *fBackendContext,
-                               message.key_type()
-                       );
-
-                       CryptoKeyType crypto_key_type = fSoResolver->invoke<CryptoKeyType, dcm_backend_context&>(
-                               "dcm_backend_key_type",
-                               *fBackendContext
-                       );
-                       contextResponse->set_key_type(crypto_key_type);
-
-                       unsigned int crypto_key_length = fSoResolver->invoke<unsigned int, dcm_backend_context&>(
-                               "dcm_backend_key_length",
-                               *fBackendContext
-                       );
-                       contextResponse->set_key_length(crypto_key_length);
-               }
-               else {
-                       LOGE("No usable backend available");
-                       throw std::invalid_argument("Unable to find backend");
-               }
+       int error = 0;
+       try {
+               fBackendContext = std::unique_ptr<dcm_backend_context>(new dcm_backend_context);
+
+               fSoResolver->invoke<void, dcm_backend_context&, const std::string&>(
+                       "dcm_backend_create_key_context", *fBackendContext, message.key_type());
+
+               CryptoKeyType crypto_key_type = fSoResolver->invoke<CryptoKeyType, dcm_backend_context&>(
+                       "dcm_backend_key_type", *fBackendContext);
+               contextResponse->set_key_type(crypto_key_type);
+
+               unsigned int crypto_key_length = fSoResolver->invoke<unsigned int, dcm_backend_context&>(
+                       "dcm_backend_key_length", *fBackendContext);
+               contextResponse->set_key_length(crypto_key_length);
+
                fCookie = (uintptr_t)fBackendContext.get();
                contextResponse->set_context_cookie(fCookie);
-       });
+       } catch(std::bad_alloc&) {
+               error = -ENOMEM;
+       } catch(std::exception&) {
+               error = -EINVAL;
+       } catch(...) {
+               error = -EFAULT;
+       }
 
        contextResponse->set_result(error);
-
        reply(msg);
 }
 
@@ -326,11 +309,11 @@ static const std::string sPEMHeader("-----BEGIN CERTIFICATE-----\n");
 
 void dcm_session::handle_cert_chain(const RequestCertificateChain& message)
 {
-       ResponseMessage msg;
-       auto * certificateResponse = msg.mutable_request_chain();
-
        LOGD("Request certificate chain");
 
+       ResponseMessage msg;
+       auto* certificateResponse = msg.mutable_request_chain();
+
        if(message.context_cookie() != fCookie) {
                LOGE("Received unknown context cookie");
                certificateResponse->set_result(-EINVAL);
@@ -347,15 +330,8 @@ void dcm_session::handle_cert_chain(const RequestCertificateChain& message)
 
        std::string cert_chain;
 
-       int error = 0;
-       bool loaded = fSoResolver->ensure_loaded();
-       if (loaded) {
-               error = fSoResolver->invoke<int, dcm_backend_context&, std::string&>(
-                       "dcm_backend_request_certificate_chain",
-                       *fBackendContext,
-                       cert_chain
-               );
-       }
+       int error = fSoResolver->invoke<int, dcm_backend_context&, std::string&>(
+               "dcm_backend_request_certificate_chain", *fBackendContext, cert_chain);
 
        if(error != 0) {
                certificateResponse->set_result(error);
@@ -364,8 +340,8 @@ void dcm_session::handle_cert_chain(const RequestCertificateChain& message)
        }
 
        if(cert_chain.length() >= sPEMHeader.length() &&
-                       !memcmp(sPEMHeader.c_str(), cert_chain.c_str(), sPEMHeader.size()) &&
-                       cert_chain[cert_chain.size() - 1] != '\0')
+               !memcmp(sPEMHeader.c_str(), cert_chain.c_str(), sPEMHeader.size()) &&
+               cert_chain[cert_chain.size() - 1] != '\0')
        {
                // Add missing 0
                cert_chain.push_back(0);
@@ -381,7 +357,7 @@ void dcm_session::handle_sign_request(const SignRequest& message)
        LOGD("Request data signing");
 
        ResponseMessage msg;
-       auto * signingResponse = msg.mutable_sign_data();
+       auto* signingResponse = msg.mutable_sign_data();
 
        if(message.context_cookie() != fCookie) {
                LOGE("Received unknown context cookie");
@@ -398,23 +374,14 @@ void dcm_session::handle_sign_request(const SignRequest& message)
        }
 
        if(message.data_to_sign().size() == 0) {
-               LOGE("Data to sign is empty and hash type is NONE");
+               LOGE("Data to sign is empty");
                signingResponse->set_result(-EINVAL);
                return;
        }
 
-       int error = 0;
-       bool loaded = fSoResolver->ensure_loaded();
-       if (loaded) {
-               error = fSoResolver->invoke<int, dcm_backend_context&, MessageDigestType, const std::string&, std::string&>(
-                       "dcm_backend_sign_crypto_data",
-                       *fBackendContext,
-                       message.digest_type(),
-                       message.data_to_sign(),
-                       *signingResponse->mutable_signature()
-               );
-       }
-       signingResponse->set_result(error);
+       int error = fSoResolver->invoke<int, dcm_backend_context&, MessageDigestType, const std::string&, std::string&>(
+                       "dcm_backend_sign_crypto_data", *fBackendContext, message.digest_type(), message.data_to_sign(), *signingResponse->mutable_signature());
 
+       signingResponse->set_result(error);
        reply(msg);
 }
similarity index 78%
rename from src/dcm-daemon/dcmsession.h
rename to src/dcm-daemon/dcm_session.h
index abddb29..0293cbb 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************
  *
- * Copyright 2017 - 2019 Samsung Electronics All Rights Reserved.
+ * Copyright 2017 - 2020 Samsung Electronics All Rights Reserved.
  *
  * Author: Jaroslaw Pelczar <j.pelczar@samsung.com>
  *
  *
  ******************************************************************/
 
-#ifndef DCM_DAEMON_DCMSESSION_H_
-#define DCM_DAEMON_DCMSESSION_H_
+#ifndef DCM_DAEMON_DCM_SESSION_H_
+#define DCM_DAEMON_DCM_SESSION_H_
 
 #include <memory>
+
 #include <boost/asio.hpp>
 #include <boost/noncopyable.hpp>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+
 #include "dcm_support.pb.h"
 #include "protobuf_asio.h"
 #include "dcm-backend-api.h"
 #include "soresolver.h"
 
-#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/io/zero_copy_stream_impl.h>
-
 class dcm_server;
 
-class dcm_session final : public std::enable_shared_from_this<dcm_session>,
-       public boost::noncopyable
+class dcm_session final : public std::enable_shared_from_this<dcm_session>, public boost::noncopyable
 {
 public:
-       dcm_session(boost::asio::io_service& io_service, boost::asio::deadline_timer& timer, const std::shared_ptr<dcm_server>& server, std::shared_ptr<so_resolver> soResolver);
+       dcm_session(boost::asio::io_service& io_service,
+               boost::asio::deadline_timer& timer,
+               const std::shared_ptr<dcm_server>& server,
+               std::shared_ptr<so_resolver> soResolver,
+               cynara* cynaraInstance,
+               unsigned int& sessionCounter);
        ~dcm_session();
 
        void start();
@@ -68,8 +73,10 @@ private:
        protobuf_async_message_deserialization                  fDeserializer;
        std::weak_ptr<dcm_server>                                               fServer;
        std::shared_ptr<dcm_backend_context>                    fBackendContext;
-       std::shared_ptr<so_resolver>                            fSoResolver;
+       std::shared_ptr<so_resolver>                                    fSoResolver;
        uint64_t                                                                                fCookie = 0;
+       cynara*                                                                                 fCynaraInstance;
+       unsigned int&                                                                   fSessionCounter;
 };
 
-#endif /* DCM_DAEMON_DCMSESSION_H_ */
+#endif /* DCM_DAEMON_DCM_SESSION_H_ */
diff --git a/src/dcm-daemon/exception_translator.h b/src/dcm-daemon/exception_translator.h
deleted file mode 100644 (file)
index 1395888..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/******************************************************************
- *
- * Copyright 2017 Samsung Electronics All Rights Reserved.
- *
- * Author: Jaroslaw Pelczar <j.pelczar@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************/
-
-#ifndef DCM_DAEMON_EXCEPTION_TRANSLATOR_H_
-#define DCM_DAEMON_EXCEPTION_TRANSLATOR_H_
-
-#include <memory>
-#include <stdexcept>
-#include <cerrno>
-#include <boost/system/system_error.hpp>
-
-template<typename T> inline int run_with_exception_handler(T t) {
-       try {
-               t();
-       } catch(boost::system::system_error& ex) {
-               return -ex.code().value();
-       } catch(std::bad_alloc&) {
-               return -ENOMEM;
-       } catch(std::domain_error&) {
-               return -EDOM;
-       } catch(std::invalid_argument&) {
-               return -EINVAL;
-       } catch(std::length_error&) {
-               return -EINVAL;
-       } catch(std::out_of_range&) {
-               return -EINVAL;
-       } catch(std::range_error&) {
-               return -ERANGE;
-       } catch(std::overflow_error&) {
-               return -EOVERFLOW;
-       } catch(std::underflow_error&) {
-               return -EOVERFLOW;
-       } catch(std::exception&) {
-               return -EINVAL;
-       } catch(...) {
-               return -EFAULT;
-       }
-
-       return 0;
-}
-
-#endif /* DCM_DAEMON_EXCEPTION_TRANSLATOR_H_ */
index 3d80489..b43b12a 100644 (file)
 #include <sys/signal.h>
 
 #include <boost/asio.hpp>
-#include <cynara-client.h>
+#include <systemd/sd-daemon.h>
 
-#include "dcmserver.h"
+#include "dcm_server.h"
 #include "log.h"
-#include "serviceadapter.h"
 
-cynara * gGlobalCynaraInstance;
-
-int main()
+boost::asio::local::stream_protocol::acceptor socket_acceptor(boost::asio::io_service& io_service)
 {
-       int error = 0;
-       service_adapter serviceAdapter;
-
-       cynara_configuration * cynara_conf = nullptr;
-       error = cynara_configuration_create(&cynara_conf);
-       if(error != CYNARA_API_SUCCESS) {
-               LOGE("Can't initialize Cynara configuration: " << error);
-               serviceAdapter.notify_start_failure(error);
-               return EXIT_FAILURE;
+       LOGD("Try to get socket from systemd");
+       int n = sd_listen_fds(0);
+       if(n > 0) {
+               for(int fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; ++fd) {
+                       if(sd_is_socket_unix(fd, SOCK_STREAM, 1, DCM_UNIX_SOCKET_PATH, 0)) {
+                               LOGD("Got UNIX domain socket with fd " << fd);
+                               return boost::asio::local::stream_protocol::acceptor(
+                                       io_service, boost::asio::local::stream_protocol(), fd);
+                       }
+               }
        }
 
-       error = cynara_initialize(&gGlobalCynaraInstance, cynara_conf);
+       LOGE("No systemd sockets found");
+       throw std::runtime_error("No socket created by systemd");
+}
 
-       cynara_configuration_destroy(cynara_conf);
+int main()
+{
+       try {
+               /* Change the file mode mask */
+               (void)umask(0);
 
-       if(error != CYNARA_API_SUCCESS) {
-               LOGE("Can't initialize Cynara instance: " << error);
-               serviceAdapter.notify_start_failure(error);
-               return EXIT_FAILURE;
-       }
+               /* Use root directory as working directory */
+               int error = chdir("/");
+               (void)error;
 
-       try {
                boost::asio::io_service io_service;
-
-               /* Catch signals */
                boost::asio::signal_set stop_signals(io_service, SIGINT, SIGTERM);
-
                stop_signals.async_wait([&io_service](const boost::system::error_code&, int sig) {
                        LOGD("Stopped by signal " << sig);
                        io_service.stop();
                });
 
-               /* Change the file mode mask */
-               (void)umask(0);
-
-               /* Use root directory as working directory */
-               error = chdir("/");
-               (void)error; // Don't care
-
-               std::string lib_backend = "libdcm-backend-api.so.1.0";
-               auto server(std::make_shared<dcm_server>(io_service, serviceAdapter.create_platform_socket_acceptor(io_service), lib_backend));
+               auto server(std::make_shared<dcm_server>(io_service, socket_acceptor(io_service)));
 
                boost::asio::signal_set hup_signals(io_service, SIGHUP);
-
                hup_signals.async_wait([](const boost::system::error_code&, int) {
                        LOGD("Received HUP signal");
                });
-
-               serviceAdapter.notify_start_complete();
-
-               LOGD("Start server");
-
                server->start();
                io_service.run();
        } catch(std::bad_alloc& e) {
-               serviceAdapter.notify_start_failure(ENOMEM);
                LOGE("Server failed with OOM exception: " << e.what());
-               return EXIT_FAILURE;
+               return EXIT_FAILURE;
        } catch(std::exception& e) {
-               serviceAdapter.notify_start_failure(EFAULT);
                LOGE("Server failed with exception: " << e.what());
                return EXIT_FAILURE;
        } catch(...) {
                LOGE("Server failed with unknown exception");
-               serviceAdapter.notify_start_failure(EFAULT);
                return EXIT_FAILURE;
        }
 
-       cynara_finish(gGlobalCynaraInstance);
-       gGlobalCynaraInstance = nullptr;
-
        LOGD("Server terminated");
-
        return 0;
 }
diff --git a/src/dcm-daemon/serviceadapter.cpp b/src/dcm-daemon/serviceadapter.cpp
deleted file mode 100644 (file)
index d03c98d..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/******************************************************************
- *
- * Copyright 2017 - 2020 Samsung Electronics All Rights Reserved.
- *
- * Author: Jaroslaw Pelczar <j.pelczar@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************/
-
-#include <cstring>
-
-#include <systemd/sd-daemon.h>
-
-#include "serviceadapter.h"
-#include "log.h"
-
-service_adapter::service_adapter()
-{
-}
-
-service_adapter::~service_adapter()
-{
-}
-
-boost::asio::local::stream_protocol::acceptor service_adapter::create_platform_socket_acceptor(boost::asio::io_service& io_service)
-{
-       LOGD("Try to get socket from systemd");
-
-       int n = sd_listen_fds(0);
-       if( n > 0 ) {
-               for(int fd = SD_LISTEN_FDS_START ; fd < SD_LISTEN_FDS_START + n ; ++fd) {
-                       if(sd_is_socket_unix(fd, SOCK_STREAM, 1, fDefaultSocketPath.c_str(), 0)) {
-                               LOGD("Got UNIX domain socket with fd " << fd);
-
-                               return boost::asio::local::stream_protocol::acceptor(
-                                       io_service,
-                                       boost::asio::local::stream_protocol(),
-                                       fd);
-                       }
-               }
-       }
-
-       LOGE("No systemd sockets found");
-
-       throw std::runtime_error("No socket created by systemd");
-}
-
-void service_adapter::notify_start_complete()
-{
-       LOGD("Notify start completed to systemd");
-
-       sd_listen_fds(1);
-       sd_notify(0, "READY=1");
-       fStartCompleteNotified = true;
-}
-
-void service_adapter::notify_start_failure(int error)
-{
-       LOGE("Notify start failure");
-
-       if(!fStartCompleteNotified) {
-               char buffer[512];
-               buffer[0] = '\0';
-               if(!strerror_r(error, buffer, sizeof(buffer)))
-                       sd_notifyf(0, "STATUS=Failed to start up: %s\nERRNO=%d", buffer, error);
-               else
-                       sd_notifyf(0, "STATUS=Failed to start up: (no message)\nERRNO=%d", error);
-       }
-}
diff --git a/src/dcm-daemon/serviceadapter.h b/src/dcm-daemon/serviceadapter.h
deleted file mode 100644 (file)
index e19e1ab..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/******************************************************************
- *
- * Copyright 2017 - 2020 Samsung Electronics All Rights Reserved.
- *
- * Author: Jaroslaw Pelczar <j.pelczar@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************/
-
-#ifndef DCM_DAEMON_SERVICEADAPTER_H_
-#define DCM_DAEMON_SERVICEADAPTER_H_
-
-#include <boost/noncopyable.hpp>
-#include <boost/asio.hpp>
-
-class service_adapter final : public boost::noncopyable {
-public:
-       service_adapter();
-       ~service_adapter();
-
-       boost::asio::local::stream_protocol::acceptor create_platform_socket_acceptor(boost::asio::io_service& io_service);
-
-       void notify_start_complete();
-       void notify_start_failure(int error);
-
-private:
-       std::string                     fDefaultSocketPath = DCM_UNIX_SOCKET_PATH;
-       bool                            fStartCompleteNotified = false;
-};
-
-#endif /* DCM_DAEMON_SERVICEADAPTER_H_ */
index 90b7ce5..68ac0d8 100644 (file)
 #include "soresolver.h"
 #include "log.h"
 
-so_resolver::so_resolver(const std::string& libraryName) :
-       fLibraryName(libraryName),
-       fLibraryHandle(nullptr)
+so_resolver::so_resolver()
 {
-}
-
-so_resolver::~so_resolver()
-{
-       if(fLibraryHandle.load(std::memory_order_relaxed)) {
-               LOGD("Unloading library " << fLibraryName);
-               dlclose(fLibraryHandle.exchange(nullptr, std::memory_order_relaxed));
-               LOGD("Unloaded library " << fLibraryName);
-       }
-}
-
-void * so_resolver::resolve_function(const std::string& name) noexcept
-{
-       std::unique_lock<std::mutex> locker(fCacheLock);
-       auto it = fCache.find(name);
-
-       if(it != fCache.end())
-               return it->second;
-
-       void * handle = fLibraryHandle.load(std::memory_order_relaxed);
-
-       if(handle) {
-               LOGD("Resolving symbol " << name << " from " << fLibraryName);
-               void * sym = dlsym(handle, name.c_str());
-               if(!sym) {
-                       LOGE("Unable to resolve symbol " << name << " from " <<
-                               fLibraryName << ": Error is " << dlerror());
-               } else {
-                       try {
-                               fCache.emplace(name, sym);
-                       } catch(...) {
-                       }
-               }
-               return sym;
-       }
-
-       LOGE("Trying to resolve symbol " << name << " from not loaded library " << fLibraryName);
-
-       return nullptr;
-}
-
-bool so_resolver::ensure_loaded() noexcept
-{
-       std::unique_lock<std::mutex> locker(fCacheLock);
-
-       void * handle = fLibraryHandle.load(std::memory_order_acquire);
-
-       if(handle)
-               return true;
-
        LOGD("Loading library " << fLibraryName);
 
-       handle = dlopen(fLibraryName.c_str(), RTLD_LAZY | RTLD_LOCAL);
-
-       if(!handle) {
+       fLibraryHandle = dlopen(fLibraryName.c_str(), RTLD_LAZY | RTLD_LOCAL);
+       if(!fLibraryHandle) {
                LOGE("Unable to load library " << fLibraryName << ": " << dlerror());
-               return false;
+               throw std::runtime_error("Unable to load backend");
        }
 
        LOGD("Library loaded " << fLibraryName);
+}
 
-       void * expectedValue = nullptr;
+so_resolver::~so_resolver()
+{
+       LOGD("Unloading library " << fLibraryName);
+       dlclose(fLibraryHandle);
+       LOGD("Unloaded library " << fLibraryName);
+}
 
-       if(!fLibraryHandle.compare_exchange_strong(expectedValue, handle, std::memory_order_release)) {
-               // Someone else have opened the library
-               dlclose(handle);
+void* so_resolver::resolve_function(const std::string& name) noexcept
+{
+       LOGD("Resolving symbol " << name << " from " << fLibraryName);
+       void* sym = dlsym(fLibraryHandle, name.c_str());
+       if(!sym) {
+               LOGE("Unable to resolve symbol " << name << " from " << fLibraryName << ": Error is " << dlerror());
        }
-
-       return true;
+       return sym;
 }
index 800e624..2bfbae2 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************
  *
- * Copyright 2017 - 2019 Samsung Electronics All Rights Reserved.
+ * Copyright 2017 - 2020 Samsung Electronics All Rights Reserved.
  *
  * Author: Jaroslaw Pelczar <j.pelczar@samsung.com>
  *
 #ifndef DCM_DAEMON_SORESOLVER_H_
 #define DCM_DAEMON_SORESOLVER_H_
 
-#include <boost/noncopyable.hpp>
 #include <string>
-#include <atomic>
 #include <stdexcept>
-#include <map>
-#include <mutex>
-#include <string>
+
+#include <boost/noncopyable.hpp>
+
+#define DCM_BACKEND "libdcm-backend-api.so.1.0"
 
 class so_resolver : public boost::noncopyable {
 public:
-       so_resolver(const std::string& libraryName);
+       so_resolver();
        ~so_resolver();
 
-       bool ensure_loaded() noexcept;
-       void * resolve_function(const std::string& name) noexcept;
+       void* resolve_function(const std::string& name) noexcept;
 
-       template<typename ReturnValue, typename... Args> ReturnValue invoke(const std::string&  name, Args... args) {
+       template<typename ReturnValue, typename... Args> ReturnValue invoke(const std::string& name, Args... args) {
                typedef ReturnValue (* function_t)(Args...);
                function_t func = (function_t)resolve_function(name);
                if(!func) {
@@ -47,10 +45,8 @@ public:
        }
 
 private:
-       std::string                                             fLibraryName;
-       std::atomic<void *>                     fLibraryHandle;
-       std::mutex                                              fCacheLock;
-       std::map<std::string, void *>   fCache;
+       std::string     fLibraryName = DCM_BACKEND;
+       void*           fLibraryHandle = nullptr;
 };
 
 #endif /* DCM_DAEMON_SORESOLVER_H_ */