Fix stopping service when no requests 22/240122/3 accepted/tizen_6.0_unified accepted/tizen_6.0_unified_hotfix tizen_6.0_hotfix accepted/tizen/6.0/unified/20201030.114853 accepted/tizen/6.0/unified/hotfix/20201103.003400 accepted/tizen/unified/20200820.133548 submit/tizen/20200806.130513 submit/tizen/20200818.093042 submit/tizen_6.0/20201029.205104 submit/tizen_6.0_hotfix/20201102.192504 submit/tizen_6.0_hotfix/20201103.114804 tizen_6.0.m2_release
authorDariusz Michaluk <d.michaluk@samsung.com>
Tue, 4 Aug 2020 12:51:18 +0000 (14:51 +0200)
committerDariusz Michaluk <d.michaluk@samsung.com>
Tue, 4 Aug 2020 15:21:00 +0000 (17:21 +0200)
Calling DCM without privilege caused session counter overflow,
which turns into stoping service while new sessions are proceed
and finally segfault.

Change-Id: If28e52aa5283978cc34ac9cdb8d7e42e2e2a5496

src/dcm-daemon/dcm_server.cpp
src/dcm-daemon/dcm_server.h
src/dcm-daemon/dcm_session.cpp
src/dcm-daemon/dcm_session.h

index efb0f5c..e034eef 100644 (file)
@@ -63,14 +63,31 @@ void dcm_server::start()
        do_accept();
 }
 
+void dcm_server::start_timer()
+{
+       LOGD("Number of active connections: " << fSessionCounter);
+       if(fSessionCounter > 0)
+               return;
+
+       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 */
+       fTimer.async_wait([this](const boost::system::error_code &error) {
+               if(error != boost::asio::error::operation_aborted) {
+                       LOGD("No active connections, server will be closed");
+                       fService.stop();
+               }
+       });
+}
+
 void dcm_server::do_accept()
 {
        auto self(this->shared_from_this());
        std::shared_ptr<dcm_session> session;
 
        try {
-               session = std::make_shared<dcm_session>(fService, fTimer, shared_from_this(),
-                       fSoResolver, fCynaraInstance, fSessionCounter);
+               session = std::make_shared<dcm_session>(fService, shared_from_this(),
+                       fSoResolver, fCynaraInstance);
        } catch(std::bad_alloc& ex) {
                LOGE("Out of memory when trying to allocate new session");
                return;
@@ -80,14 +97,17 @@ void dcm_server::do_accept()
        }
 
        LOGD("Start accepting connections");
-       session->start_timer();
+       self->start_timer();
 
        fAcceptor.async_accept(session->socket(),
                [session, self](boost::system::error_code error_code)
                {
                        if(!error_code) {
-                               LOGD("Accepted session");
+                               self->fSessionCounter++;
+                               LOGD("Accepted session, number of active connections: " << self->fSessionCounter);
+                               self->fTimer.cancel();
                                session->start();
+                               self->fSessionCounter--;
                        } else {
                                LOGE("Can't accept new session " << error_code);
                        }
index 199f066..128976b 100644 (file)
@@ -38,6 +38,7 @@ public:
 
 private:
        void do_accept();
+       void start_timer();
 
 private:
        boost::asio::io_service&                                                fService;
index a430620..6b7d3de 100644 (file)
 #include "log.h"
 
 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,
-       cynara* cynaraInstance,
-       unsigned int& sessionCounter) :
-               fService(io_service),
-               fTimer(timer),
+       cynara* cynaraInstance) :
                fSocket(io_service),
                fServer(server),
                fSoResolver(soResolver),
-               fCynaraInstance(cynaraInstance),
-               fSessionCounter(sessionCounter)
+               fCynaraInstance(cynaraInstance)
 {
        LOGD("Create new session object " << this);
-       fSessionCounter++;
 }
 
 dcm_session::~dcm_session()
@@ -58,41 +52,12 @@ void dcm_session::start()
        LOGD("Accepted connection with socket " << fSocket.native_handle());
 
        if(verify_privileges(handle)) {
-               stop_timer();
                do_receive();
        } else {
                LOGE("Client privilege check failure. Disconnect");
-               start_timer();
        }
 }
 
-void dcm_session::start_timer()
-{
-       fSessionCounter--;
-       LOGD("Number of active connections: " << fSessionCounter);
-
-       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 */
-               fTimer.async_wait([this](const boost::system::error_code &error) {
-                       if(error != boost::asio::error::operation_aborted) {
-                               LOGD("No active connections, server will be closed");
-                               fService.stop();
-                       }
-               });
-       }
-}
-
-void dcm_session::stop_timer()
-{
-       fSessionCounter++;
-       LOGD("Number of active connections: " << fSessionCounter);
-
-       fTimer.cancel();
-       LOGD("Timer cancelled");
-}
-
 void dcm_session::do_receive() noexcept
 {
        try {
@@ -108,7 +73,6 @@ void dcm_session::do_receive() noexcept
                                } else {
                                        LOGE("Client disconnected: " << error);
                                        // Connection object will be released by shared ptr
-                                       start_timer();
                                }
                        });
        } catch(std::exception& ex) {
index 0293cbb..b621f1b 100644 (file)
@@ -39,16 +39,12 @@ class dcm_session final : public std::enable_shared_from_this<dcm_session>, publ
 {
 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,
-               cynara* cynaraInstance,
-               unsigned int& sessionCounter);
+               cynara* cynaraInstance);
        ~dcm_session();
 
        void start();
-       void start_timer();
-       void stop_timer();
 
        inline boost::asio::local::stream_protocol::socket& socket() {
                return fSocket;
@@ -66,8 +62,6 @@ private:
        void handle_sign_request(const SignRequest& message);
 
 private:
-       boost::asio::io_service&                                                fService;
-       boost::asio::deadline_timer&                                    fTimer;
        boost::asio::local::stream_protocol::socket             fSocket;
        protobuf_async_message_serialization                    fSerializer;
        protobuf_async_message_deserialization                  fDeserializer;
@@ -76,7 +70,6 @@ private:
        std::shared_ptr<so_resolver>                                    fSoResolver;
        uint64_t                                                                                fCookie = 0;
        cynara*                                                                                 fCynaraInstance;
-       unsigned int&                                                                   fSessionCounter;
 };
 
 #endif /* DCM_DAEMON_DCM_SESSION_H_ */