]> git.stg.codes - stg.git/commitdiff
Complete replacement notifiers with subscriptions.
authorMaksym Mamontov <madf@madf.info>
Fri, 26 Aug 2022 11:57:38 +0000 (14:57 +0300)
committerMaksym Mamontov <madf@madf.info>
Fri, 26 Aug 2022 11:57:38 +0000 (14:57 +0300)
24 files changed:
include/stg/notifer.h [deleted file]
include/stg/rs_packets.h
include/stg/subscriptions.h
include/stg/user.h
include/stg/user_property.h
projects/rscriptd/listener.cpp
projects/rscriptd/listener.h
projects/stargazer/plugins/authorization/ao/ao.cpp
projects/stargazer/plugins/authorization/ao/ao.h
projects/stargazer/plugins/authorization/inetaccess/inetaccess.h
projects/stargazer/plugins/other/ping/ping.cpp
projects/stargazer/plugins/other/ping/ping.h
projects/stargazer/plugins/other/rscript/rscript.cpp
projects/stargazer/plugins/other/rscript/rscript.h
projects/stargazer/plugins/other/rscript/ur_functor.h
projects/stargazer/plugins/other/smux/handlers.cpp
projects/stargazer/plugins/other/smux/smux.cpp
projects/stargazer/plugins/other/smux/smux.h
projects/stargazer/traffcounter_impl.cpp
projects/stargazer/traffcounter_impl.h
projects/stargazer/user_impl.cpp
projects/stargazer/user_impl.h
projects/stargazer/users_impl.h
tests/test_reconnect_on_tariff_change.cpp

diff --git a/include/stg/notifer.h b/include/stg/notifer.h
deleted file mode 100644 (file)
index 339b617..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#pragma once
-
-namespace STG
-{
-
-template <typename... Ts>
-struct NotifierBase
-{
-    virtual ~NotifierBase() = default;
-
-    virtual void notify(const Ts&... values) = 0;
-};
-
-template <typename T>
-using PropertyNotifierBase = NotifierBase<T, T>;
-
-}
index 0c31e22820f655eac1c1a93a59a3d9e2ccc7c7fe..6faea5259a669ec49d37531c65005b58d7ff84c8 100644 (file)
@@ -19,8 +19,7 @@
  *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
  */
 
-#ifndef RS_PACKETSH
-#define RS_PACKETSH
+#pragma once
 
 #define RS_MAGIC_LEN        (6)
 #define RS_PROTO_VER_LEN    (2)
@@ -36,7 +35,7 @@
 
 #include <cstdint>
 
-namespace RS
+namespace STG::RS
 {
 
 struct PACKET_HEADER
@@ -58,5 +57,3 @@ int8_t              padding[7];
 } __attribute__((__packed__)); // 992 bytes, 124 blocks
 
 } // namespace RS
-
-#endif
index a50cbba3a90364023b58850961bc062f25a5412f..9ee9c64a6c3c8d2af9c989d9069dfa7a6bd389b7 100644 (file)
@@ -10,24 +10,23 @@ namespace STG
 class Connection
 {
     public:
-        Connection() noexcept : m_connected(false) {}
+        Connection() = default;
 
         Connection(const Connection&) = delete;
         Connection& operator=(const Connection&) = delete;
         Connection(Connection&&) = default;
         Connection& operator=(Connection&&) = default;
 
-        Connection(const std::function<void ()>& f) noexcept : m_disconnect(f), m_connected(true) {}
+        Connection(const std::function<void ()>& f) noexcept : m_disconnect(f) {}
         void disconnect() noexcept
         {
-            if (!m_connected)
+            if (!m_disconnect)
                 return;
             m_disconnect();
-            m_connected = false;
+            m_disconnect = {};
         }
     private:
         std::function<void ()> m_disconnect;
-        bool m_connected;
 };
 
 class ScopedConnection
index b08f3cd0629603dab00900fb22a3e3aa584f5b65..78b602ba25a679050a4978e78714be2a379380c3 100644 (file)
@@ -20,8 +20,8 @@
 
 #pragma once
 
-#include "notifer.h"
 #include "message.h"
+#include "user_property.h"
 
 #include <vector>
 #include <string>
@@ -37,77 +37,91 @@ class UserProperties;
 class DirTraff;
 struct Auth;
 
-using CURR_IP_NOTIFIER = PropertyNotifierBase<uint32_t>;
-using CONNECTED_NOTIFIER = PropertyNotifierBase<bool>;
+class User
+{
+    public:
+        User() noexcept
+            : m_connectedBase(false),
+              m_currIPBase(0),
+              m_connected(m_connectedBase),
+              m_currIP(m_currIPBase)
+        {
+        }
+
+        virtual ~User() = default;
 
-struct User {
-    virtual ~User() = default;
+        virtual int                 WriteConf() = 0;
+        virtual int                 WriteStat() = 0;
 
-    virtual int                 WriteConf() = 0;
-    virtual int                 WriteStat() = 0;
+        virtual const std::string&  GetLogin() const = 0;
 
-    virtual const std::string&  GetLogin() const = 0;
+        uint32_t                    GetCurrIP() const { return m_currIP; }
+        time_t                      GetCurrIPModificationTime() const { return m_currIP.ModificationTime(); }
 
-    virtual uint32_t            GetCurrIP() const = 0;
-    virtual time_t              GetCurrIPModificationTime() const = 0;
+        template <typename F>
+        auto                        beforeCurrIPChange(F&& f) { return m_currIP.beforeChange(std::forward<F>(f)); }
+        template <typename F>
+        auto                        afterCurrIPChange(F&& f) { return m_currIP.afterChange(std::forward<F>(f)); }
 
-    virtual void                AddCurrIPBeforeNotifier(CURR_IP_NOTIFIER* notifier) = 0;
-    virtual void                DelCurrIPBeforeNotifier(const CURR_IP_NOTIFIER* notifier) = 0;
+        template <typename F>
+        auto                        beforeConnectedChange(F&& f) { return m_connected.beforeChange(std::forward<F>(f)); }
+        template <typename F>
+        auto                        afterConnectedChange(F&& f) { return m_connected.afterChange(std::forward<F>(f)); }
 
-    virtual void                AddCurrIPAfterNotifier(CURR_IP_NOTIFIER* notifier) = 0;
-    virtual void                DelCurrIPAfterNotifier(const CURR_IP_NOTIFIER* notifier) = 0;
+        virtual int                 GetID() const = 0;
 
-    virtual void                AddConnectedBeforeNotifier(CONNECTED_NOTIFIER* notifier) = 0;
-    virtual void                DelConnectedBeforeNotifier(const CONNECTED_NOTIFIER* notifier) = 0;
+        virtual double              GetPassiveTimePart() const = 0;
 
-    virtual void                AddConnectedAfterNotifier(CONNECTED_NOTIFIER* notifier) = 0;
-    virtual void                DelConnectedAfterNotifier(const CONNECTED_NOTIFIER* notifier) = 0;
+        virtual const Tariff*       GetTariff() const = 0;
+        virtual void                ResetNextTariff() = 0;
 
-    virtual int                 GetID() const = 0;
+        virtual const DirTraff&     GetSessionUpload() const = 0;
+        virtual const DirTraff&     GetSessionDownload() const = 0;
+        virtual time_t              GetSessionUploadModificationTime() const = 0;
+        virtual time_t              GetSessionDownloadModificationTime() const = 0;
 
-    virtual double              GetPassiveTimePart() const = 0;
+        bool                        GetConnected() const { return m_connected; }
+        time_t                      GetConnectedModificationTime() const { return m_connected.ModificationTime(); }
 
-    virtual const Tariff*       GetTariff() const = 0;
-    virtual void                ResetNextTariff() = 0;
+        virtual const std::string&  GetLastDisconnectReason() const = 0;
+        virtual int                 GetAuthorized() const = 0;
+        virtual time_t              GetAuthorizedModificationTime() const = 0;
 
-    virtual const DirTraff&     GetSessionUpload() const = 0;
-    virtual const DirTraff&     GetSessionDownload() const = 0;
-    virtual time_t              GetSessionUploadModificationTime() const = 0;
-    virtual time_t              GetSessionDownloadModificationTime() const = 0;
+        virtual bool                IsAuthorizedBy(const Auth * auth) const = 0;
+        virtual std::vector<std::string> GetAuthorizers() const = 0;
 
-    virtual bool                GetConnected() const = 0;
-    virtual time_t              GetConnectedModificationTime() const = 0;
-    virtual const std::string&  GetLastDisconnectReason() const = 0;
-    virtual int                 GetAuthorized() const = 0;
-    virtual time_t              GetAuthorizedModificationTime() const = 0;
+        virtual int                 AddMessage(Message* msg) = 0;
 
-    virtual bool                IsAuthorizedBy(const Auth * auth) const = 0;
-    virtual std::vector<std::string> GetAuthorizers() const = 0;
+        virtual void                UpdatePingTime(time_t t = 0) = 0;
+        virtual time_t              GetPingTime() const = 0;
 
-    virtual int                 AddMessage(Message* msg) = 0;
+        virtual void                Run() = 0;
 
-    virtual void                UpdatePingTime(time_t t = 0) = 0;
-    virtual time_t              GetPingTime() const = 0;
+        virtual const std::string&  GetStrError() const = 0;
 
-    virtual void                Run() = 0;
+        virtual UserProperties&     GetProperties() = 0;
+        virtual const UserProperties& GetProperties() const = 0;
 
-    virtual const std::string&  GetStrError() const = 0;
+        virtual bool                GetDeleted() const = 0;
+        virtual void                SetDeleted() = 0;
 
-    virtual UserProperties&     GetProperties() = 0;
-    virtual const UserProperties& GetProperties() const = 0;
+        virtual time_t              GetLastWriteStatTime() const = 0;
 
-    virtual bool                GetDeleted() const = 0;
-    virtual void                SetDeleted() = 0;
+        virtual bool                IsInetable() = 0;
+        virtual std::string         GetEnabledDirs() const = 0;
 
-    virtual time_t              GetLastWriteStatTime() const = 0;
+        virtual void                OnAdd() = 0;
+        virtual void                OnDelete() = 0;
 
-    virtual bool                IsInetable() = 0;
-    virtual std::string         GetEnabledDirs() const = 0;
+        virtual std::string GetParamValue(const std::string& name) const = 0;
 
-    virtual void                OnAdd() = 0;
-    virtual void                OnDelete() = 0;
+    private:
+        bool m_connectedBase;
+        uint32_t m_currIPBase;
 
-    virtual std::string GetParamValue(const std::string& name) const = 0;
+    protected:
+        UserProperty<bool> m_connected;
+        UserProperty<uint32_t> m_currIP;
 };
 
 }
index 529d854acd669b63b2d054fd36f61530f19f82e0..d73a636b2df42b82ae0296f395dfd6ef4caac6d4 100644 (file)
@@ -4,7 +4,7 @@
 #include "stg/user_ips.h"
 #include "stg/store.h"
 #include "stg/admin.h"
-#include "stg/notifer.h"
+#include "stg/subscriptions.h"
 #include "stg/admin_conf.h"
 #include "stg/logger.h"
 #include "stg/locker.h"
@@ -25,7 +25,8 @@
 namespace STG
 {
 //-----------------------------------------------------------------------------
-struct UserPropertyBase {
+struct UserPropertyBase
+{
     virtual ~UserPropertyBase() = default;
     virtual std::string ToString() const = 0;
 };
@@ -33,7 +34,8 @@ struct UserPropertyBase {
 using Registry = std::map<std::string, UserPropertyBase*>;
 //-----------------------------------------------------------------------------
 template<typename T>
-class UserProperty : public UserPropertyBase {
+class UserProperty : public UserPropertyBase
+{
     public:
         explicit UserProperty(T& val);
 
@@ -47,11 +49,10 @@ class UserProperty : public UserPropertyBase {
 
         operator const T&() const noexcept { return value; }
 
-        void AddBeforeNotifier(PropertyNotifierBase<T>* n);
-        void DelBeforeNotifier(const PropertyNotifierBase<T>* n);
-
-        void AddAfterNotifier(PropertyNotifierBase<T>* n);
-        void DelAfterNotifier(const PropertyNotifierBase<T>* n);
+        template <typename F>
+        auto beforeChange(F&& f) { return m_beforeCallbacks.add(std::forward<F>(f)); }
+        template <typename F>
+        auto afterChange(F&& f) { return m_afterCallbacks.add(std::forward<F>(f)); }
 
         time_t ModificationTime() const noexcept { return modificationTime; }
         void   ModifyTime() noexcept;
@@ -60,13 +61,14 @@ class UserProperty : public UserPropertyBase {
     private:
         T& value;
         time_t modificationTime;
-        std::set<PropertyNotifierBase<T>*> beforeNotifiers;
-        std::set<PropertyNotifierBase<T>*> afterNotifiers;
+        Subscriptions<T, T> m_beforeCallbacks;
+        Subscriptions<T, T> m_afterCallbacks;
         std::mutex mutex;
 };
 //-----------------------------------------------------------------------------
 template<typename T>
-class UserPropertyLogged: public UserProperty<T> {
+class UserPropertyLogged: public UserProperty<T>
+{
     public:
         UserPropertyLogged(T& val,
                            const std::string& n,
@@ -110,7 +112,8 @@ class UserPropertyLogged: public UserProperty<T> {
         const Settings& settings;
 };
 //-----------------------------------------------------------------------------
-class UserProperties {
+class UserProperties
+{
     /*
      В этом месте важен порядок следования приватной и открытой частей.
      Это связано с тем, что часть которая находится в публичной секции
@@ -184,9 +187,7 @@ template <typename T>
 inline
 UserProperty<T>::UserProperty(T& val)
     : value(val),
-      modificationTime(time(NULL)),
-      beforeNotifiers(),
-      afterNotifiers()
+      modificationTime(time(NULL))
 {
 }
 //-----------------------------------------------------------------------------
@@ -199,22 +200,18 @@ void UserProperty<T>::ModifyTime() noexcept
 //-----------------------------------------------------------------------------
 template <typename T>
 inline
-void UserProperty<T>::Set(const T& rvalue)
+void UserProperty<T>::Set(const T& rhs)
 {
     std::lock_guard<std::mutex> lock(mutex);
 
     T oldVal = value;
 
-    auto ni = beforeNotifiers.begin();
-    while (ni != beforeNotifiers.end())
-        (*ni++)->notify(oldVal, rvalue);
+    m_beforeCallbacks.notify(oldVal, rhs);
 
-    value = rvalue;
+    value = rhs;
     modificationTime = time(NULL);
 
-    ni = afterNotifiers.begin();
-    while (ni != afterNotifiers.end())
-        (*ni++)->notify(oldVal, rvalue);
+    m_afterCallbacks.notify(oldVal, rhs);
 }
 //-----------------------------------------------------------------------------
 template <typename T>
@@ -225,38 +222,6 @@ UserProperty<T>& UserProperty<T>::operator=(const T& newValue)
     return *this;
 }
 //-----------------------------------------------------------------------------
-template <typename T>
-inline
-void UserProperty<T>::AddBeforeNotifier(PropertyNotifierBase<T>* n)
-{
-    std::lock_guard<std::mutex> lock(mutex);
-    beforeNotifiers.insert(n);
-}
-//-----------------------------------------------------------------------------
-template <typename T>
-inline
-void UserProperty<T>::DelBeforeNotifier(const PropertyNotifierBase<T>* n)
-{
-    std::lock_guard<std::mutex> lock(mutex);
-    beforeNotifiers.erase(const_cast<PropertyNotifierBase<T>*>(n));
-}
-//-----------------------------------------------------------------------------
-template <typename T>
-inline
-void UserProperty<T>::AddAfterNotifier(PropertyNotifierBase<T>* n)
-{
-    std::lock_guard<std::mutex> lock(mutex);
-    afterNotifiers.insert(n);
-}
-//-----------------------------------------------------------------------------
-template <typename T>
-inline
-void UserProperty<T>::DelAfterNotifier(const PropertyNotifierBase<T>* n)
-{
-    std::lock_guard<std::mutex> lock(mutex);
-    afterNotifiers.erase(const_cast<PropertyNotifierBase<T>*>(n));
-}
-//-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 template <typename T>
index b168e5e226fe8f1304d775660312351ed47a1222..a1193527b9bc3d7c9f4f9969e6bcf31655c6b8bd 100644 (file)
@@ -199,7 +199,7 @@ bool LISTENER::RecvPacket(const std::stop_token& token)
 struct iovec iov[2];
 
 char buffer[RS_MAX_PACKET_LEN];
-RS::PACKET_HEADER packetHead;
+STG::RS::PACKET_HEADER packetHead;
 
 iov[0].iov_base = reinterpret_cast<char *>(&packetHead);
 iov[0].iov_len = sizeof(packetHead);
@@ -266,7 +266,7 @@ return false;
 //-----------------------------------------------------------------------------
 bool LISTENER::GetParams(char * buffer, UserData & data)
 {
-RS::PACKET_TAIL packetTail;
+STG::RS::PACKET_TAIL packetTail;
 
 DecryptString(&packetTail, buffer, sizeof(packetTail), &ctxS);
 
@@ -407,7 +407,7 @@ else
 return false;
 }
 //-----------------------------------------------------------------------------
-bool LISTENER::CheckHeader(const RS::PACKET_HEADER & header) const
+bool LISTENER::CheckHeader(const STG::RS::PACKET_HEADER & header) const
 {
 if (strncmp(reinterpret_cast<const char*>(header.magic), RS_ID, RS_MAGIC_LEN))
     return true;
index 4d36b87a1ac7534b339cb609a1e3d1b3b708e8a3..473ce556c580b5d7043d73404fccbcc7d8225c11 100644 (file)
@@ -87,7 +87,7 @@ private:
     bool                FinalizeNet();
     bool                RecvPacket(const std::stop_token& token);
     // Parsing stuff
-    bool                CheckHeader(const RS::PACKET_HEADER & header) const;
+    bool                CheckHeader(const STG::RS::PACKET_HEADER & header) const;
     bool                GetParams(char * buffer, UserData & data);
     // Processing stuff
     void                ProcessPending();
index 355c7061663699b9894b98980406bd7377d6de50..cb9a804d4b14acc66f087976639b23e3a3587981 100644 (file)
@@ -32,6 +32,8 @@
 
 #include <unistd.h>
 
+using STG::AUTH_AO;
+
 extern "C" STG::Plugin* GetPlugin()
 {
     static AUTH_AO plugin;
@@ -48,7 +50,7 @@ return "Always Online authorizator v.1.0";
 AUTH_AO::AUTH_AO()
     : users(NULL),
       isRunning(false),
-      logger(STG::PluginLogger::get("auth_ao"))
+      logger(PluginLogger::get("auth_ao"))
 {
 }
 //-----------------------------------------------------------------------------
@@ -76,88 +78,28 @@ if (!isRunning)
 m_onAddUserConn.disconnect();
 m_onDelUserConn.disconnect();
 
-auto it = userList.begin();
-while (it != userList.end())
-    {
-    if ((*it)->IsAuthorizedBy(this))
-        users->Unauthorize((*it)->GetLogin(), this);
-    UnSetUserNotifiers(*it);
-    ++it;
-    }
+m_conns.clear();
+
 isRunning = false;
 return 0;
 }
 //-----------------------------------------------------------------------------
 void AUTH_AO::SetUserNotifiers(UserPtr u)
 {
-// ---------- AlwaysOnline -------------------
-CHG_BEFORE_NOTIFIER<int> BeforeChgAONotifier(*this, u);
-CHG_AFTER_NOTIFIER<int>  AfterChgAONotifier(*this, u);
-
-BeforeChgAONotifierList.push_front(BeforeChgAONotifier);
-AfterChgAONotifierList.push_front(AfterChgAONotifier);
-
-u->GetProperties().alwaysOnline.AddBeforeNotifier(&BeforeChgAONotifierList.front());
-u->GetProperties().alwaysOnline.AddAfterNotifier(&AfterChgAONotifierList.front());
-// ---------- AlwaysOnline end ---------------
-
-// ---------- IP -------------------
-CHG_BEFORE_NOTIFIER<STG::UserIPs> BeforeChgIPNotifier(*this, u);
-CHG_AFTER_NOTIFIER<STG::UserIPs>  AfterChgIPNotifier(*this, u);
-
-BeforeChgIPNotifierList.push_front(BeforeChgIPNotifier);
-AfterChgIPNotifierList.push_front(AfterChgIPNotifier);
-
-u->GetProperties().ips.AddBeforeNotifier(&BeforeChgIPNotifierList.front());
-u->GetProperties().ips.AddAfterNotifier(&AfterChgIPNotifierList.front());
-// ---------- IP end ---------------
+    m_conns.emplace_back(
+        u->GetID(),
+        u->GetProperties().alwaysOnline.beforeChange([this, u](auto, auto){ Unauthorize(u); }),
+        u->GetProperties().alwaysOnline.afterChange([this, u](auto, auto){ UpdateUserAuthorization(u); }),
+        u->GetProperties().ips.beforeChange([this, u](const auto&, const auto&){ Unauthorize(u); }),
+        u->GetProperties().ips.afterChange([this, u](const auto&, const auto&){ UpdateUserAuthorization(u); })
+    );
 }
 //-----------------------------------------------------------------------------
 void AUTH_AO::UnSetUserNotifiers(UserPtr u)
 {
-// ---      AlwaysOnline        ---
-auto aoBIter = find_if(BeforeChgAONotifierList.begin(),
-                       BeforeChgAONotifierList.end(),
-                       [u](auto notifier){ return notifier.GetUser() == u; });
-
-if (aoBIter != BeforeChgAONotifierList.end())
-    {
-    aoBIter->GetUser()->GetProperties().alwaysOnline.DelBeforeNotifier(&(*aoBIter));
-    BeforeChgAONotifierList.erase(aoBIter);
-    }
-
-auto aoAIter = find_if(AfterChgAONotifierList.begin(),
-                       AfterChgAONotifierList.end(),
-                       [u](auto notifier){ return notifier.GetUser() == u; });
-
-if (aoAIter != AfterChgAONotifierList.end())
-    {
-    aoAIter->GetUser()->GetProperties().alwaysOnline.DelAfterNotifier(&(*aoAIter));
-    AfterChgAONotifierList.erase(aoAIter);
-    }
-// ---      AlwaysOnline end    ---
-
-// ---          IP              ---
-auto ipBIter = std::find_if(BeforeChgIPNotifierList.begin(),
-                            BeforeChgIPNotifierList.end(),
-                            [u](auto notifier){ return notifier.GetUser() == u; });
-
-if (ipBIter != BeforeChgIPNotifierList.end())
-    {
-    ipBIter->GetUser()->GetProperties().ips.DelBeforeNotifier(&(*ipBIter));
-    BeforeChgIPNotifierList.erase(ipBIter);
-    }
-
-auto ipAIter = find_if(AfterChgIPNotifierList.begin(),
-                       AfterChgIPNotifierList.end(),
-                       [u](auto notifier){ return notifier.GetUser() == u; });
-
-if (ipAIter != AfterChgIPNotifierList.end())
-    {
-    ipAIter->GetUser()->GetProperties().ips.DelAfterNotifier(&(*ipAIter));
-    AfterChgIPNotifierList.erase(ipAIter);
-    }
-// ---          IP end          ---
+    m_conns.erase(std::remove_if(m_conns.begin(), m_conns.end(),
+                                 [u](const auto& c){ return std::get<0>(c) == u->GetID(); }),
+                  m_conns.end());
 }
 //-----------------------------------------------------------------------------
 void AUTH_AO::GetUsers()
@@ -202,22 +144,14 @@ UnSetUserNotifiers(u);
 userList.erase(std::remove(userList.begin(), userList.end(), u), userList.end());
 }
 //-----------------------------------------------------------------------------
-int AUTH_AO::SendMessage(const STG::Message &, uint32_t) const
+int AUTH_AO::SendMessage(const Message &, uint32_t) const
 {
 errorStr = "Authorization modele \'AlwaysOnline\' does not support sending messages";
 return -1;
 }
 //-----------------------------------------------------------------------------
-template <typename varParamType>
-void CHG_BEFORE_NOTIFIER<varParamType>::notify(const varParamType &, const varParamType &)
+void AUTH_AO::Unauthorize(UserPtr user)
 {
-if (user->IsAuthorizedBy(&auth))
-    auth.users->Unauthorize(user->GetLogin(), &auth);
+    if (user->IsAuthorizedBy(this))
+        users->Unauthorize(user->GetLogin(), this);
 }
-//-----------------------------------------------------------------------------
-template <typename varParamType>
-void CHG_AFTER_NOTIFIER<varParamType>::notify(const varParamType &, const varParamType &)
-{
-auth.UpdateUserAuthorization(user);
-}
-//-----------------------------------------------------------------------------
index 18b4142971d2ef6635e2609a8915649248d9a748..add62d4ee42a1a72453b3cc96c22f0af44533b60 100644 (file)
@@ -23,7 +23,6 @@
 #include "stg/auth.h"
 #include "stg/module_settings.h"
 #include "stg/store.h"
-#include "stg/notifer.h"
 #include "stg/subscriptions.h"
 #include "stg/user_ips.h"
 #include "stg/user.h"
 namespace STG
 {
 struct Users;
-}
 
 class AUTH_AO;
 
-using UserPtr = STG::User*;
-using ConstUserPtr = const STG::User*;
-
-template <typename T>
-class CHG_BEFORE_NOTIFIER : public STG::PropertyNotifierBase<T> {
-public:
-                CHG_BEFORE_NOTIFIER(AUTH_AO & a, UserPtr u)
-                    : user(u), auth(a) {}
-                CHG_BEFORE_NOTIFIER(const CHG_BEFORE_NOTIFIER<T> & rvalue)
-                    : user(rvalue.user), auth(rvalue.auth) {}
-    void        notify(const T & oldValue, const T & newValue) override;
-    UserPtr    GetUser() const { return user; }
-
-private:
-    CHG_BEFORE_NOTIFIER<T> & operator=(const CHG_BEFORE_NOTIFIER<T> & rvalue);
-
-    UserPtr        user;
-    const AUTH_AO & auth;
-};
+using UserPtr = User*;
+using ConstUserPtr = const User*;
 //-----------------------------------------------------------------------------
-template <typename T>
-class CHG_AFTER_NOTIFIER : public STG::PropertyNotifierBase<T> {
-public:
-                CHG_AFTER_NOTIFIER(AUTH_AO & a, UserPtr u)
-                    : user(u), auth(a) {}
-                CHG_AFTER_NOTIFIER(const CHG_AFTER_NOTIFIER<T> & rvalue)
-                    : user(rvalue.user), auth(rvalue.auth) {}
-    void        notify(const T & oldValue, const T & newValue) override;
-    UserPtr    GetUser() const { return user; }
-
-private:
-    CHG_AFTER_NOTIFIER<T> & operator=(const CHG_AFTER_NOTIFIER<T> & rvalue);
-
-    UserPtr        user;
-    const AUTH_AO & auth;
+class AUTH_AO : public Auth
+{
+    public:
+        AUTH_AO();
+
+        void                SetUsers(Users * u) override { users = u; }
+
+        int                 Start() override;
+        int                 Stop() override;
+        int                 Reload(const ModuleSettings & /*ms*/) override { return 0; }
+        bool                IsRunning() override { return isRunning; }
+        void                SetSettings(const ModuleSettings &) override {}
+        int                 ParseSettings() override { return 0; }
+        const std::string & GetStrError() const override { return errorStr; }
+        std::string         GetVersion() const override;
+        uint16_t            GetStartPosition() const override { return 30; }
+        uint16_t            GetStopPosition() const override { return 30; }
+
+        int                 SendMessage(const Message & msg, uint32_t ip) const override;
+
+    private:
+        AUTH_AO(const AUTH_AO & rvalue);
+        AUTH_AO & operator=(const AUTH_AO & rvalue);
+
+        void                AddUser(UserPtr u);
+        void                DelUser(UserPtr u);
+
+        void                GetUsers();
+        void                SetUserNotifiers(UserPtr u);
+        void                UnSetUserNotifiers(UserPtr u);
+        void                UpdateUserAuthorization(ConstUserPtr u) const;
+        void                Unauthorize(UserPtr u);
+
+        mutable std::string errorStr;
+        Users *             users;
+        std::vector<UserPtr> userList;
+        bool                isRunning;
+        ModuleSettings     settings;
+
+        using ConnHolder = std::tuple<int, ScopedConnection, ScopedConnection, ScopedConnection, ScopedConnection>;
+        std::vector<ConnHolder> m_conns;
+
+        ScopedConnection m_onAddUserConn;
+        ScopedConnection m_onDelUserConn;
+
+        PluginLogger logger;
 };
-//-----------------------------------------------------------------------------
-class AUTH_AO : public STG::Auth {
-public:
-    AUTH_AO();
-
-    void                SetUsers(STG::Users * u) override { users = u; }
-
-    int                 Start() override;
-    int                 Stop() override;
-    int                 Reload(const STG::ModuleSettings & /*ms*/) override { return 0; }
-    bool                IsRunning() override { return isRunning; }
-    void                SetSettings(const STG::ModuleSettings &) override {}
-    int                 ParseSettings() override { return 0; }
-    const std::string & GetStrError() const override { return errorStr; }
-    std::string         GetVersion() const override;
-    uint16_t            GetStartPosition() const override { return 30; }
-    uint16_t            GetStopPosition() const override { return 30; }
-
-    int                 SendMessage(const STG::Message & msg, uint32_t ip) const override;
-
-private:
-    AUTH_AO(const AUTH_AO & rvalue);
-    AUTH_AO & operator=(const AUTH_AO & rvalue);
 
-    void                AddUser(UserPtr u);
-    void                DelUser(UserPtr u);
-
-    void                GetUsers();
-    void                SetUserNotifiers(UserPtr u);
-    void                UnSetUserNotifiers(UserPtr u);
-    void                UpdateUserAuthorization(ConstUserPtr u) const;
-
-    mutable std::string errorStr;
-    STG::Users *             users;
-    std::vector<UserPtr> userList;
-    bool                isRunning;
-    STG::ModuleSettings     settings;
-
-    std::list<CHG_BEFORE_NOTIFIER<int> >      BeforeChgAONotifierList;
-    std::list<CHG_AFTER_NOTIFIER<int> >       AfterChgAONotifierList;
-
-    std::list<CHG_BEFORE_NOTIFIER<STG::UserIPs> > BeforeChgIPNotifierList;
-    std::list<CHG_AFTER_NOTIFIER<STG::UserIPs> >  AfterChgIPNotifierList;
-
-    STG::ScopedConnection m_onAddUserConn;
-    STG::ScopedConnection m_onDelUserConn;
-
-    STG::PluginLogger logger;
-
-    friend class CHG_BEFORE_NOTIFIER<int>;
-    friend class CHG_AFTER_NOTIFIER<int>;
-    friend class CHG_BEFORE_NOTIFIER<STG::UserIPs>;
-    friend class CHG_AFTER_NOTIFIER<STG::UserIPs>;
-
-};
+}
index d620f3927df3e98e44c1d9f86cf565bb42da0a36..65c15c7b7d0abd9356885000262da8db9674b470 100644 (file)
@@ -22,7 +22,6 @@
 #include "stg/auth.h"
 #include "stg/store.h"
 #include "stg/module_settings.h"
-#include "stg/notifer.h"
 #include "stg/user_ips.h"
 #include "stg/user.h"
 #include "stg/users.h"
index 71752de60719ef461981f9f060dc2d85ebc29a8f..db081f7e5af12ab75b50dbeb1ca1f4b03a7d5a2a 100644 (file)
@@ -4,43 +4,32 @@
 #include "stg/locker.h"
 #include "stg/user_property.h"
 
+#include <algorithm>
 #include <cstdio>
 #include <cassert>
 #include <csignal>
 #include <ctime>
-#include <algorithm>
+
+using STG::PING;
+using STG::PING_SETTINGS;
 
 namespace
 {
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-template <typename varType>
-class HAS_USER: public std::binary_function<varType, UserPtr, bool>
-{
-public:
-    explicit HAS_USER(const UserPtr & u) : user(u) {}
-    bool operator()(varType notifier) const
-        {
-        return notifier.GetUser() == user;
-        }
-private:
-    const UserPtr & user;
-};
-}
 
 extern "C" STG::Plugin* GetPlugin()
 {
     static PING plugin;
     return &plugin;
 }
+
+}
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-int PING_SETTINGS::ParseSettings(const STG::ModuleSettings & s)
+int PING_SETTINGS::ParseSettings(const ModuleSettings & s)
 {
-STG::ParamValue pv;
-std::vector<STG::ParamValue>::const_iterator pvi;
+ParamValue pv;
+std::vector<ParamValue>::const_iterator pvi;
 
 pv.param = "PingDelay";
 pvi = std::find(s.moduleParams.begin(), s.moduleParams.end(), pv);
@@ -63,7 +52,7 @@ return 0;
 PING::PING()
     : users(nullptr),
       isRunning(false),
-      logger(STG::PluginLogger::get("ping"))
+      logger(PluginLogger::get("ping"))
 {
 }
 //-----------------------------------------------------------------------------
@@ -112,13 +101,7 @@ for (int i = 0; i < 25; i++)
 m_onAddUserConn.disconnect();
 m_onDelUserConn.disconnect();
 
-std::list<UserPtr>::iterator users_iter;
-users_iter = usersList.begin();
-while (users_iter != usersList.end())
-    {
-    UnSetUserNotifiers(*users_iter);
-    ++users_iter;
-    }
+m_conns.clear();
 
 if (isRunning)
     m_thread.detach();
@@ -191,47 +174,18 @@ isRunning = false;
 //-----------------------------------------------------------------------------
 void PING::SetUserNotifiers(UserPtr u)
 {
-CHG_CURRIP_NOTIFIER_PING ChgCurrIPNotifier(*this, u);
-CHG_IPS_NOTIFIER_PING ChgIPNotifier(*this, u);
-
-ChgCurrIPNotifierList.push_front(ChgCurrIPNotifier);
-ChgIPNotifierList.push_front(ChgIPNotifier);
-
-u->AddCurrIPAfterNotifier(&(*ChgCurrIPNotifierList.begin()));
-u->GetProperties().ips.AddAfterNotifier(&(*ChgIPNotifierList.begin()));
+    m_conns.emplace_back(
+        u->GetID(),
+        u->afterCurrIPChange([this](auto oldVal, auto newVal){ updateCurrIP(oldVal, newVal); }),
+        u->GetProperties().ips.afterChange([this](const auto& oldVal, const auto& newVal){ updateIPs(oldVal, newVal); })
+    );
 }
 //-----------------------------------------------------------------------------
 void PING::UnSetUserNotifiers(UserPtr u)
 {
-// ---          CurrIP              ---
-HAS_USER<CHG_CURRIP_NOTIFIER_PING> IsContainsUserCurrIP(u);
-HAS_USER<CHG_IPS_NOTIFIER_PING> IsContainsUserIP(u);
-
-std::list<CHG_CURRIP_NOTIFIER_PING>::iterator currIPter;
-std::list<CHG_IPS_NOTIFIER_PING>::iterator IPIter;
-
-currIPter = find_if(ChgCurrIPNotifierList.begin(),
-                    ChgCurrIPNotifierList.end(),
-                    IsContainsUserCurrIP);
-
-if (currIPter != ChgCurrIPNotifierList.end())
-    {
-    currIPter->GetUser()->DelCurrIPAfterNotifier(&(*currIPter));
-    ChgCurrIPNotifierList.erase(currIPter);
-    }
-// ---         CurrIP end          ---
-
-// ---          IP              ---
-IPIter = find_if(ChgIPNotifierList.begin(),
-                 ChgIPNotifierList.end(),
-                 IsContainsUserIP);
-
-if (IPIter != ChgIPNotifierList.end())
-    {
-    IPIter->GetUser()->GetProperties().ips.DelAfterNotifier(&(*IPIter));
-    ChgIPNotifierList.erase(IPIter);
-    }
-// ---          IP end          ---
+    m_conns.erase(std::remove_if(m_conns.begin(), m_conns.end(),
+                                 [u](const auto& c){ return std::get<0>(c) == u->GetID(); }),
+                  m_conns.end());
 }
 //-----------------------------------------------------------------------------
 void PING::GetUsers()
@@ -289,18 +243,18 @@ while (users_iter != usersList.end())
     }
 }
 //-----------------------------------------------------------------------------
-void CHG_CURRIP_NOTIFIER_PING::notify(const uint32_t & oldIP, const uint32_t & newIP)
+void PING::updateCurrIP(uint32_t oldVal, uint32_t newVal)
 {
-ping.pinger.DelIP(oldIP);
-if (newIP != 0)
-    ping.pinger.AddIP(newIP);
+    pinger.DelIP(oldVal);
+    if (newVal != 0)
+        pinger.AddIP(newVal);
 }
 //-----------------------------------------------------------------------------
-void CHG_IPS_NOTIFIER_PING::notify(const STG::UserIPs & oldIPS, const STG::UserIPs & newIPS)
+void PING::updateIPs(const UserIPs& oldVal, const UserIPs& newVal)
 {
-if (oldIPS.onlyOneIP())
-    ping.pinger.DelIP(oldIPS[0].ip);
+    if (oldVal.onlyOneIP())
+        pinger.DelIP(oldVal[0].ip);
 
-if (newIPS.onlyOneIP())
-    ping.pinger.AddIP(newIPS[0].ip);
+    if (newVal.onlyOneIP())
+        pinger.AddIP(newVal[0].ip);
 }
index 68d79794afd27cc77428a9d43119447525401ea0..aaa2988a723f9f14eb054126c0b613639eb81147 100644 (file)
@@ -2,7 +2,6 @@
 
 #include "stg/plugin.h"
 #include "stg/module_settings.h"
-#include "stg/notifer.h"
 #include "stg/subscriptions.h"
 #include "stg/user_ips.h"
 #include "stg/pinger.h"
@@ -10,6 +9,8 @@
 #include "stg/logger.h"
 
 #include <string>
+#include <vector>
+#include <tuple>
 #include <list>
 #include <mutex>
 #pragma GCC diagnostic push
 #pragma GCC diagnostic pop
 #include <cstdint>
 
-class PING;
-
 namespace STG
 {
 struct USER;
 struct SETTINGS;
-}
-
-using UserPtr = STG::User*;
-//-----------------------------------------------------------------------------*/
-class CHG_CURRIP_NOTIFIER_PING: public STG::PropertyNotifierBase<uint32_t> {
-public:
-    CHG_CURRIP_NOTIFIER_PING(const PING & p, UserPtr u)
-        : user(u), ping(p) {}
-    void notify(const uint32_t & oldIP, const uint32_t & newIP) override;
-    UserPtr GetUser() const { return user; }
 
-private:
-    CHG_CURRIP_NOTIFIER_PING & operator=(const CHG_CURRIP_NOTIFIER_PING &);
-
-    UserPtr user;
-    const PING & ping;
-};
-//-----------------------------------------------------------------------------
-class CHG_IPS_NOTIFIER_PING: public STG::PropertyNotifierBase<STG::UserIPs> {
-public:
-    CHG_IPS_NOTIFIER_PING(const PING & p, UserPtr u)
-        : user(u), ping(p) {}
-    void notify(const STG::UserIPs & oldIPS, const STG::UserIPs & newIPS) override;
-    UserPtr GetUser() const { return user; }
-
-private:
-    CHG_IPS_NOTIFIER_PING & operator=(const CHG_IPS_NOTIFIER_PING &);
-
-    UserPtr user;
-    const PING & ping;
-};
+using UserPtr = User*;
 //-----------------------------------------------------------------------------
-class PING_SETTINGS {
-public:
-    PING_SETTINGS() : pingDelay(0) {}
-    const std::string & GetStrError() const { return errorStr; }
-    int ParseSettings(const STG::ModuleSettings & s);
-    int GetPingDelay() const { return pingDelay; }
-private:
-    int pingDelay;
-    mutable std::string errorStr;
+class PING_SETTINGS
+{
+    public:
+        PING_SETTINGS() : pingDelay(0) {}
+        const std::string & GetStrError() const { return errorStr; }
+        int ParseSettings(const ModuleSettings & s);
+        int GetPingDelay() const { return pingDelay; }
+    private:
+        int pingDelay;
+        std::string errorStr;
 };
 //-----------------------------------------------------------------------------
-class PING : public STG::Plugin {
-friend class CHG_CURRIP_NOTIFIER_PING;
-friend class CHG_IPS_NOTIFIER_PING;
-public:
-    PING();
-
-    void SetUsers(STG::Users * u) override { users = u; }
-    void SetSettings(const STG::ModuleSettings & s) override { settings = s; }
-    int ParseSettings() override;
-
-    int Start() override;
-    int Stop() override;
-    int Reload(const STG::ModuleSettings & /*ms*/) override { return 0; }
-    bool IsRunning() override;
-
-    const std::string & GetStrError() const override { return errorStr; }
-    std::string GetVersion() const override { return "Pinger v.1.01"; }
-    uint16_t GetStartPosition() const override { return 10; }
-    uint16_t GetStopPosition() const override { return 10; }
-
-    void AddUser(UserPtr u);
-    void DelUser(UserPtr u);
-
-private:
-    explicit PING(const PING & rvalue);
-    PING & operator=(const PING & rvalue);
-
-    void GetUsers();
-    void SetUserNotifiers(UserPtr u);
-    void UnSetUserNotifiers(UserPtr u);
-    void Run(std::stop_token token);
-
-    mutable std::string errorStr;
-    PING_SETTINGS pingSettings;
-    STG::ModuleSettings settings;
-    STG::Users * users;
-    std::list<UserPtr> usersList;
-
-    std::jthread m_thread;
-    std::mutex m_mutex;
-    bool isRunning;
-    mutable STG_PINGER pinger;
-
-    std::list<CHG_CURRIP_NOTIFIER_PING> ChgCurrIPNotifierList;
-    std::list<CHG_IPS_NOTIFIER_PING> ChgIPNotifierList;
-
-    STG::ScopedConnection m_onAddUserConn;
-    STG::ScopedConnection m_onDelUserConn;
-
-    STG::PluginLogger logger;
+class PING : public Plugin
+{
+    public:
+        PING();
+
+        void SetUsers(Users * u) override { users = u; }
+        void SetSettings(const ModuleSettings & s) override { settings = s; }
+        int ParseSettings() override;
+
+        int Start() override;
+        int Stop() override;
+        int Reload(const ModuleSettings & /*ms*/) override { return 0; }
+        bool IsRunning() override;
+
+        const std::string & GetStrError() const override { return errorStr; }
+        std::string GetVersion() const override { return "Pinger v.1.01"; }
+        uint16_t GetStartPosition() const override { return 10; }
+        uint16_t GetStopPosition() const override { return 10; }
+
+        void AddUser(UserPtr u);
+        void DelUser(UserPtr u);
+
+    private:
+        explicit PING(const PING & rvalue);
+        PING & operator=(const PING & rvalue);
+
+        void GetUsers();
+        void SetUserNotifiers(UserPtr u);
+        void UnSetUserNotifiers(UserPtr u);
+        void Run(std::stop_token token);
+
+        mutable std::string errorStr;
+        PING_SETTINGS pingSettings;
+        ModuleSettings settings;
+        Users * users;
+        std::list<UserPtr> usersList;
+
+        std::jthread m_thread;
+        std::mutex m_mutex;
+        bool isRunning;
+        mutable STG_PINGER pinger;
+
+        void updateCurrIP(uint32_t oldVal, uint32_t newVal);
+        void updateIPs(const UserIPs& oldVal, const UserIPs& newVal);
+
+        ScopedConnection m_onAddUserConn;
+        ScopedConnection m_onDelUserConn;
+
+        using ConnHolder = std::tuple<int, ScopedConnection, ScopedConnection>;
+        std::vector<ConnHolder> m_conns;
+
+        PluginLogger logger;
 };
+
+}
index f8dc9d99bed486b8f2cee38b45a4d96fdbbb3d21..36e84be832cc1a7c68cfadd2095238840730dfe1 100644 (file)
 
 extern volatile time_t stgTime;
 
+namespace RS = STG::RS;
 using RS::REMOTE_SCRIPT;
 
-namespace {
-
-template<typename T>
-struct USER_IS
-{
-    explicit USER_IS(RS::UserPtr u) : user(u) {}
-    bool operator()(const T & notifier) { return notifier.GetUser() == user; }
-
-    RS::UserPtr user;
-};
-
-} // namespace anonymous
-
 extern "C" STG::Plugin* GetPlugin()
 {
     static REMOTE_SCRIPT plugin;
@@ -74,10 +62,10 @@ RS::SETTINGS::SETTINGS()
 {
 }
 //-----------------------------------------------------------------------------
-int RS::SETTINGS::ParseSettings(const STG::ModuleSettings & s)
+int RS::SETTINGS::ParseSettings(const ModuleSettings & s)
 {
 int p;
-STG::ParamValue pv;
+ParamValue pv;
 netRouters.clear();
 ///////////////////////////
 pv.param = "Port";
@@ -147,7 +135,7 @@ NRMapParser nrMapParser;
 if (!nrMapParser.ReadFile(subnetFile))
     netRouters = nrMapParser.GetMap();
 else
-    STG::PluginLogger::get("rscript")("mod_rscript: error opening subnets file '%s'", subnetFile.c_str());
+    PluginLogger::get("rscript")("mod_rscript: error opening subnets file '%s'", subnetFile.c_str());
 
 return 0;
 }
@@ -160,7 +148,7 @@ REMOTE_SCRIPT::REMOTE_SCRIPT()
       isRunning(false),
       users(nullptr),
       sock(0),
-      logger(STG::PluginLogger::get("rscript"))
+      logger(PluginLogger::get("rscript"))
 {
 }
 //-----------------------------------------------------------------------------
@@ -223,10 +211,10 @@ if (!IsRunning())
 m_thread.request_stop();
 
 std::for_each(
-        authorizedUsers.begin(),
-        authorizedUsers.end(),
-        DisconnectUser(*this)
-        );
+    authorizedUsers.begin(),
+    authorizedUsers.end(),
+    [this](auto& kv){ Send(kv.second, true); }
+);
 
 FinalizeNet();
 
@@ -251,7 +239,7 @@ else
 return 0;
 }
 //-----------------------------------------------------------------------------
-int REMOTE_SCRIPT::Reload(const STG::ModuleSettings & /*ms*/)
+int REMOTE_SCRIPT::Reload(const ModuleSettings & /*ms*/)
 {
 NRMapParser nrMapParser;
 
@@ -469,20 +457,18 @@ return {};
 //-----------------------------------------------------------------------------
 void REMOTE_SCRIPT::SetUserNotifiers(UserPtr u)
 {
-ipNotifierList.push_front(RS::IP_NOTIFIER(*this, u));
-connNotifierList.push_front(RS::CONNECTED_NOTIFIER(*this, u));
+    m_conns.emplace_back(
+        u->GetID(),
+        u->afterCurrIPChange([this, u](auto, auto newVal){ addDelUser(u, newVal != 0); }),
+        u->afterConnectedChange([this, u](auto, auto newVal){ addDelUser(u, newVal); })
+    );
 }
 //-----------------------------------------------------------------------------
 void REMOTE_SCRIPT::UnSetUserNotifiers(UserPtr u)
 {
-ipNotifierList.erase(std::remove_if(ipNotifierList.begin(),
-                                    ipNotifierList.end(),
-                                    USER_IS<IP_NOTIFIER>(u)),
-                     ipNotifierList.end());
-connNotifierList.erase(std::remove_if(connNotifierList.begin(),
-                                      connNotifierList.end(),
-                                      USER_IS<CONNECTED_NOTIFIER>(u)),
-                       connNotifierList.end());
+    m_conns.erase(std::remove_if(m_conns.begin(), m_conns.end(),
+                  [u](const auto& c){ return std::get<0>(c) == u->GetID(); }),
+                  m_conns.end());
 
 }
 //-----------------------------------------------------------------------------
@@ -517,20 +503,12 @@ if (it != authorizedUsers.end())
     }*/
 }
 //-----------------------------------------------------------------------------
-void RS::IP_NOTIFIER::notify(const uint32_t & /*oldValue*/, const uint32_t & newValue)
+void REMOTE_SCRIPT::addDelUser(UserPtr user, bool toAdd)
 {
-if (newValue != 0)
-    rs.AddRSU(user);
-else
-    rs.DelRSU(user);
-}
-//-----------------------------------------------------------------------------
-void RS::CONNECTED_NOTIFIER::notify(const bool & /*oldValue*/, const bool & newValue)
-{
-if (newValue)
-    rs.AddRSU(user);
-else
-    rs.DelRSU(user);
+    if (toAdd)
+        AddRSU(user);
+    else
+        DelRSU(user);
 }
 //-----------------------------------------------------------------------------
 void REMOTE_SCRIPT::InitEncrypt(const std::string & password) const
index d0bf1e7e262f3d82fd23f7dab3b41e441861b4d6..a27e2eff4e2de7b37d6485d110fb5cc44cf1b964 100644 (file)
@@ -24,7 +24,6 @@
 #include "stg/plugin.h"
 #include "stg/module_settings.h"
 #include "stg/subscriptions.h"
-#include "stg/notifer.h"
 #include "stg/user.h"
 #include "stg/blowfish.h"
 #include "stg/rs_packets.h"
@@ -48,69 +47,16 @@ namespace STG
 {
 struct Settings;
 struct Settings;
-}
 
 namespace RS
 {
 
-class REMOTE_SCRIPT;
+using UserPtr = User*;
 class UpdateRouter;
-class DisconnectUser;
-
-using UserPtr = STG::User*;
-
-//-----------------------------------------------------------------------------
-class IP_NOTIFIER: public STG::PropertyNotifierBase<uint32_t> {
-public:
-    IP_NOTIFIER(REMOTE_SCRIPT & r, UserPtr u)
-        : user(u), rs(r) { user->AddCurrIPAfterNotifier(this); }
-    IP_NOTIFIER(const IP_NOTIFIER & rhs)
-        : user(rhs.user), rs(rhs.rs) { user->AddCurrIPAfterNotifier(this); }
-    ~IP_NOTIFIER() { user->DelCurrIPAfterNotifier(this); }
-
-    IP_NOTIFIER & operator=(const IP_NOTIFIER & rhs)
-    {
-        user->DelCurrIPAfterNotifier(this);
-        user = rhs.user;
-        user->AddCurrIPAfterNotifier(this);
-        return *this;
-    }
-
-    void notify(const uint32_t & oldValue, const uint32_t & newValue) override;
-    UserPtr GetUser() const { return user; }
-
-private:
-
-    UserPtr user;
-    REMOTE_SCRIPT & rs;
-};
-//-----------------------------------------------------------------------------
-class CONNECTED_NOTIFIER: public STG::PropertyNotifierBase<bool> {
-public:
-    CONNECTED_NOTIFIER(REMOTE_SCRIPT & r, UserPtr u)
-        : user(u), rs(r) { user->AddConnectedAfterNotifier(this); }
-    CONNECTED_NOTIFIER(const CONNECTED_NOTIFIER & rhs)
-        : user(rhs.user), rs(rhs.rs) { user->AddConnectedAfterNotifier(this); }
-    ~CONNECTED_NOTIFIER() { user->DelConnectedAfterNotifier(this); }
-
-    CONNECTED_NOTIFIER & operator=(const CONNECTED_NOTIFIER & rhs)
-    {
-        user->DelConnectedAfterNotifier(this);
-        user = rhs.user;
-        user->AddConnectedAfterNotifier(this);
-        return *this;
-    }
-
-    void notify(const bool & oldValue, const bool & newValue) override;
-    UserPtr GetUser() const { return user; }
-
-private:
 
-    UserPtr user;
-    REMOTE_SCRIPT & rs;
-};
 //-----------------------------------------------------------------------------
-struct USER {
+struct USER
+{
     USER(const std::vector<uint32_t> & r, UserPtr it)
         : lastSentTime(0),
           user(it),
@@ -126,118 +72,110 @@ struct USER {
     uint32_t ip;
 };
 //-----------------------------------------------------------------------------
-class SETTINGS {
-public:
-                        SETTINGS();
-    virtual             ~SETTINGS() {}
-    const std::string & GetStrError() const { return errorStr; }
-    int                 ParseSettings(const STG::ModuleSettings & s);
-    int                 GetSendPeriod() const { return sendPeriod; }
-    uint16_t            GetPort() const { return port; }
-    const std::vector<NET_ROUTER> & GetSubnetsMap() const { return netRouters; }
-    const std::vector<std::string> & GetUserParams() const { return userParams; }
-    const std::string & GetPassword() const { return password; }
-    const std::string & GetMapFileName() const { return subnetFile; }
-
-private:
-    int                 sendPeriod;
-    uint16_t            port;
-    std::string         errorStr;
-    std::vector<NET_ROUTER> netRouters;
-    std::vector<std::string> userParams;
-    std::string         password;
-    std::string         subnetFile;
+class SETTINGS
+{
+    public:
+                            SETTINGS();
+        virtual             ~SETTINGS() {}
+        const std::string & GetStrError() const { return errorStr; }
+        int                 ParseSettings(const ModuleSettings & s);
+        int                 GetSendPeriod() const { return sendPeriod; }
+        uint16_t            GetPort() const { return port; }
+        const std::vector<NET_ROUTER> & GetSubnetsMap() const { return netRouters; }
+        const std::vector<std::string> & GetUserParams() const { return userParams; }
+        const std::string & GetPassword() const { return password; }
+        const std::string & GetMapFileName() const { return subnetFile; }
+
+    private:
+        int                 sendPeriod;
+        uint16_t            port;
+        std::string         errorStr;
+        std::vector<NET_ROUTER> netRouters;
+        std::vector<std::string> userParams;
+        std::string         password;
+        std::string         subnetFile;
 };
 //-----------------------------------------------------------------------------
-class REMOTE_SCRIPT : public STG::Plugin {
-public:
-                        REMOTE_SCRIPT();
+class REMOTE_SCRIPT : public Plugin
+{
+    public:
+                            REMOTE_SCRIPT();
+
+        void                SetUsers(Users * u) override { users = u; }
+        void                SetSettings(const ModuleSettings & s) override { settings = s; }
+        int                 ParseSettings() override;
 
-    void                SetUsers(STG::Users * u) override { users = u; }
-    void                SetSettings(const STG::ModuleSettings & s) override { settings = s; }
-    int                 ParseSettings() override;
+        int                 Start() override;
+        int                 Stop() override;
+        int                 Reload(const ModuleSettings & ms) override;
+        bool                IsRunning() override { return isRunning; }
 
-    int                 Start() override;
-    int                 Stop() override;
-    int                 Reload(const STG::ModuleSettings & ms) override;
-    bool                IsRunning() override { return isRunning; }
+        const std::string & GetStrError() const override { return errorStr; }
+        std::string         GetVersion() const override { return "Remote script v 0.3"; }
+        uint16_t            GetStartPosition() const override { return 10; }
+        uint16_t            GetStopPosition() const override { return 10; }
 
-    const std::string & GetStrError() const override { return errorStr; }
-    std::string         GetVersion() const override { return "Remote script v 0.3"; }
-    uint16_t            GetStartPosition() const override { return 10; }
-    uint16_t            GetStopPosition() const override { return 10; }
+        void                DelUser(UserPtr u) { UnSetUserNotifiers(u); }
+        void                AddUser(UserPtr u) { SetUserNotifiers(u); }
 
-    void                DelUser(UserPtr u) { UnSetUserNotifiers(u); }
-    void                AddUser(UserPtr u) { SetUserNotifiers(u); }
+        void                AddRSU(UserPtr user);
+        void                DelRSU(UserPtr user);
 
-    void                AddRSU(UserPtr user);
-    void                DelRSU(UserPtr user);
+    private:
+        REMOTE_SCRIPT(const REMOTE_SCRIPT & rhs);
+        REMOTE_SCRIPT & operator=(const REMOTE_SCRIPT & rhs);
 
-private:
-    REMOTE_SCRIPT(const REMOTE_SCRIPT & rhs);
-    REMOTE_SCRIPT & operator=(const REMOTE_SCRIPT & rhs);
+        void                Run(std::stop_token token);
+        bool                PrepareNet();
+        bool                FinalizeNet();
 
-    void                Run(std::stop_token token);
-    bool                PrepareNet();
-    bool                FinalizeNet();
+        bool                Send(USER & rsu, bool forceDisconnect = false) const;
+        bool                SendDirect(USER & rsu, uint32_t routerIP, bool forceDisconnect = false) const;
+        bool                PreparePacket(char * buf, size_t bufSize, USER &rsu, bool forceDisconnect = false) const;
+        void                PeriodicSend();
 
-    bool                Send(USER & rsu, bool forceDisconnect = false) const;
-    bool                SendDirect(USER & rsu, uint32_t routerIP, bool forceDisconnect = false) const;
-    bool                PreparePacket(char * buf, size_t bufSize, USER &rsu, bool forceDisconnect = false) const;
-    void                PeriodicSend();
+        std::vector<uint32_t> IP2Routers(uint32_t ip);
+        bool                GetUsers();
 
-    std::vector<uint32_t> IP2Routers(uint32_t ip);
-    bool                GetUsers();
+        void                SetUserNotifiers(UserPtr u);
+        void                UnSetUserNotifiers(UserPtr u);
 
-    void                SetUserNotifiers(UserPtr u);
-    void                UnSetUserNotifiers(UserPtr u);
+        void                InitEncrypt(const std::string & password) const;
+        void                Encrypt(void * dst, const void * src, size_t len8) const;
 
-    void                InitEncrypt(const std::string & password) const;
-    void                Encrypt(void * dst, const void * src, size_t len8) const;
+        mutable BLOWFISH_CTX ctx;
+        std::map<uint32_t, USER> authorizedUsers;
 
-    mutable BLOWFISH_CTX ctx;
+        mutable std::string errorStr;
+        SETTINGS         rsSettings;
+        ModuleSettings     settings;
+        int                 sendPeriod;
+        int                 halfPeriod;
 
-    std::list<IP_NOTIFIER> ipNotifierList;
-    std::list<CONNECTED_NOTIFIER> connNotifierList;
-    std::map<uint32_t, USER> authorizedUsers;
+        bool                isRunning;
 
-    mutable std::string errorStr;
-    SETTINGS         rsSettings;
-    STG::ModuleSettings     settings;
-    int                 sendPeriod;
-    int                 halfPeriod;
+        Users *             users;
 
-    bool                isRunning;
+        std::vector<NET_ROUTER> netRouters;
 
-    STG::Users *             users;
+        std::jthread        m_thread;
+        std::mutex          m_mutex;
 
-    std::vector<NET_ROUTER> netRouters;
+        int                 sock;
 
-    std::jthread        m_thread;
-    std::mutex          m_mutex;
+        ScopedConnection m_onAddUserConn;
+        ScopedConnection m_onDelUserConn;
 
-    int                 sock;
+        void addDelUser(UserPtr user, bool toAdd);
 
-    STG::ScopedConnection m_onAddUserConn;
-    STG::ScopedConnection m_onDelUserConn;
+        using ConnHolder = std::tuple<int, ScopedConnection, ScopedConnection>;
+        std::vector<ConnHolder> m_conns;
 
-    STG::PluginLogger       logger;
+        PluginLogger       logger;
 
-    friend class RS::UpdateRouter;
-    friend class RS::DisconnectUser;
-    friend class RS::CONNECTED_NOTIFIER;
-};
-//-----------------------------------------------------------------------------
-class DisconnectUser : public std::unary_function<std::pair<const uint32_t, USER> &, void> {
-    public:
-        explicit DisconnectUser(REMOTE_SCRIPT & rs) : rscript(rs) {}
-        void operator()(std::pair<const uint32_t, USER> & p)
-        {
-            rscript.Send(p.second, true);
-        }
-    private:
-        REMOTE_SCRIPT & rscript;
+        friend class RS::UpdateRouter;
 };
 //-----------------------------------------------------------------------------
 
 } // namespace RS
+}
index 95b03ea244d2fae6e0d06d1ca423fa39279bf780..a4addc834632847c21a7712a8afedaf3031be4a1 100644 (file)
@@ -18,8 +18,7 @@
  *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
  */
 
-#ifndef __UR_FUNCTOR_H__
-#define __UR_FUNCTOR_H__
+#pragma once
 
 #include "rscript.h"
 
 #include <utility>
 #include <cstdint>
 
-namespace RS
+namespace STG::RS
 {
 
 class UpdateRouter : public std::unary_function<std::pair<const uint32_t, RS::USER>, void>
 {
-public:
-    explicit UpdateRouter(REMOTE_SCRIPT & t)
-        : obj(t) {}
+    public:
+        explicit UpdateRouter(REMOTE_SCRIPT & t)
+            : obj(t) {}
 
-    void operator() (std::pair<const uint32_t, USER> & val)
-        {
-        std::vector<uint32_t> newRouters = obj.IP2Routers(val.second.ip);
-        std::vector<uint32_t>::const_iterator oldIt(val.second.routers.begin());
-        std::vector<uint32_t>::const_iterator newIt(newRouters.begin());
-        val.second.shortPacketsCount = 0;
-        while (oldIt != val.second.routers.end() ||
-               newIt != newRouters.end())
+        void operator() (std::pair<const uint32_t, USER> & val)
             {
-            if (oldIt == val.second.routers.end())
+            std::vector<uint32_t> newRouters = obj.IP2Routers(val.second.ip);
+            std::vector<uint32_t>::const_iterator oldIt(val.second.routers.begin());
+            std::vector<uint32_t>::const_iterator newIt(newRouters.begin());
+            val.second.shortPacketsCount = 0;
+            while (oldIt != val.second.routers.end() ||
+                   newIt != newRouters.end())
                 {
-                if (newIt != newRouters.end())
+                if (oldIt == val.second.routers.end())
+                    {
+                    if (newIt != newRouters.end())
+                        {
+                        obj.SendDirect(val.second, *newIt); // Connect on new router
+                        ++newIt;
+                        }
+                    }
+                else if (newIt == newRouters.end())
+                    {
+                    obj.SendDirect(val.second, *oldIt, true); // Disconnect on old router
+                    ++oldIt;
+                    }
+                else if (*oldIt < *newIt)
+                    {
+                    obj.SendDirect(val.second, *oldIt, true); // Disconnect on old router
+                    ++oldIt;
+                    }
+                else if (*oldIt > *newIt)
                     {
                     obj.SendDirect(val.second, *newIt); // Connect on new router
                     ++newIt;
                     }
+                else
+                    {
+                    ++oldIt;
+                    if (newIt != newRouters.end())
+                        ++newIt;
+                    }
                 }
-            else if (newIt == newRouters.end())
-                {
-                obj.SendDirect(val.second, *oldIt, true); // Disconnect on old router
-                ++oldIt;
-                }
-            else if (*oldIt < *newIt)
-                {
-                obj.SendDirect(val.second, *oldIt, true); // Disconnect on old router
-                ++oldIt;
-                }
-            else if (*oldIt > *newIt)
-                {
-                obj.SendDirect(val.second, *newIt); // Connect on new router
-                ++newIt;
-                }
-            else
-                {
-                ++oldIt;
-                if (newIt != newRouters.end())
-                    ++newIt;
-                }
+            val.second.routers = newRouters;
             }
-        val.second.routers = newRouters;
-        }
-private:
-    REMOTE_SCRIPT & obj;
+    private:
+        REMOTE_SCRIPT & obj;
 };
 
 } // namespace RS
-
-#endif
index ac179da9cc28ba6b0ae040c3e4e2d4aa7fb8f8ee..cce188c8ca46ca33c30fa2bec369cb80ac26ace4 100644 (file)
@@ -10,6 +10,8 @@
 #include "utils.h"
 #include "smux.h"
 
+using STG::SMUX;
+
 #ifdef SMUX_DEBUG
 bool SMUX::CloseHandler(const SMUX_PDUs_t * pdus)
 {
index 07f9d20035d8800c7fcb65f1213e2958fad9d9c3..59d93105a2f3a398e94aff9b6c76980d81efaf16 100644 (file)
@@ -19,6 +19,9 @@
 #include "smux.h"
 #include "utils.h"
 
+using STG::SMUX;
+using STG::SMUX_SETTINGS;
+
 namespace
 {
 
@@ -41,9 +44,9 @@ SMUX_SETTINGS::SMUX_SETTINGS()
       port(0)
 {}
 
-int SMUX_SETTINGS::ParseSettings(const STG::ModuleSettings & s)
+int SMUX_SETTINGS::ParseSettings(const ModuleSettings & s)
 {
-STG::ParamValue pv;
+ParamValue pv;
 int p;
 
 pv.param = "Port";
@@ -100,7 +103,7 @@ SMUX::SMUX()
       lastReconnectTry(0),
       reconnectTimeout(1),
       sock(-1),
-      logger(STG::PluginLogger::get("smux"))
+      logger(PluginLogger::get("smux"))
 {
 smuxHandlers[SMUX_PDUs_PR_close] = &SMUX::CloseHandler;
 smuxHandlers[SMUX_PDUs_PR_registerResponse] = &SMUX::RegisterResponseHandler;
@@ -226,7 +229,7 @@ printfd(__FILE__, "SMUX::Stop() - After\n");
 return 0;
 }
 
-int SMUX::Reload(const STG::ModuleSettings & /*ms*/)
+int SMUX::Reload(const ModuleSettings & /*ms*/)
 {
 if (Stop() != 0)
     return -1;
@@ -411,23 +414,17 @@ return true;
 
 void SMUX::SetNotifier(UserPtr userPtr)
 {
-notifiers.emplace_back(*this, userPtr);
-userPtr->GetProperties().tariffName.AddAfterNotifier(&notifiers.back());
+    m_conns.emplace_back(
+        userPtr->GetID(),
+        userPtr->GetProperties().tariffName.afterChange([this](const auto&, const auto&){ UpdateTables(); })
+    );
 }
 
 void SMUX::UnsetNotifier(UserPtr userPtr)
 {
-auto it = notifiers.begin();
-while (it != notifiers.end())
-    {
-    if (it->GetUserPtr() == userPtr)
-        {
-        userPtr->GetProperties().tariffName.DelAfterNotifier(&(*it));
-        notifiers.erase(it);
-        break;
-        }
-    ++it;
-    }
+    m_conns.erase(std::remove_if(m_conns.begin(), m_conns.end(),
+                                 [userPtr](const auto& c){ return std::get<0>(c) == userPtr->GetID(); }),
+                  m_conns.end());
 }
 
 void SMUX::SetNotifiers()
@@ -450,7 +447,7 @@ m_onDelUserConn = users->onDel([this](auto user){
     UpdateTables();
 });
 
-auto updateTables = [this](const STG::TariffData&){ UpdateTables(); };
+auto updateTables = [this](const TariffData&){ UpdateTables(); };
 m_onAddTariffConn = tariffs->onAdd(updateTables);
 m_onDelTariffConn = tariffs->onDel(updateTables);
 }
@@ -463,11 +460,5 @@ m_onDelTariffConn.disconnect();
 m_onAddUserConn.disconnect();
 m_onDelUserConn.disconnect();
 
-auto it = notifiers.begin();
-while (it != notifiers.end())
-    {
-    it->GetUserPtr()->GetProperties().tariffName.DelAfterNotifier(&(*it));
-    ++it;
-    }
-notifiers.clear();
+m_conns.clear();
 }
index 3e708e2b70342da1a45a70be6c2d3acd77dd3e48..bb62c7c0a03a9c7001f934ff8ee8d4ee7c67954d 100644 (file)
@@ -10,7 +10,6 @@
 #include "stg/plugin.h"
 #include "stg/module_settings.h"
 #include "stg/subscriptions.h"
-#include "stg/notifer.h"
 #include "stg/noncopyable.h"
 #include "stg/logger.h"
 
@@ -33,7 +32,6 @@ struct Tariffs;
 struct Services;
 struct Corporations;
 struct TraffCounter;
-}
 
 class SMUX;
 
@@ -42,135 +40,115 @@ typedef bool (SMUX::*PDUsHandler)(const PDUs_t * pdus);
 typedef std::map<SMUX_PDUs_PR, SMUXPacketHandler> SMUXHandlers;
 typedef std::map<PDUs_PR, PDUsHandler> PDUsHandlers;
 
-using UserPtr = STG::User*;
-//-----------------------------------------------------------------------------
-class SMUX_SETTINGS {
-public:
-    SMUX_SETTINGS();
-    virtual ~SMUX_SETTINGS() {}
-    const std::string & GetStrError() const { return errorStr; }
-    int ParseSettings(const STG::ModuleSettings & s);
-
-    uint32_t GetIP() const { return ip; }
-    uint16_t GetPort() const { return port; }
-    const std::string GetPassword() const { return password; }
-
-private:
-    mutable std::string errorStr;
-
-    uint32_t ip;
-    uint16_t port;
-    std::string password;
-};
+using UserPtr = User*;
 //-----------------------------------------------------------------------------
-class CHG_AFTER_NOTIFIER : public STG::PropertyNotifierBase<std::string> {
-public:
-             CHG_AFTER_NOTIFIER(SMUX & s, const UserPtr & u)
-                 : STG::PropertyNotifierBase<std::string>(),
-                   smux(s), userPtr(u) {}
-             CHG_AFTER_NOTIFIER(const CHG_AFTER_NOTIFIER & rvalue)
-                 : STG::PropertyNotifierBase<std::string>(),
-                   smux(rvalue.smux), userPtr(rvalue.userPtr) {}
-    void     notify(const std::string &, const std::string &) override;
-
-    UserPtr GetUserPtr() const { return userPtr; }
-
-private:
-    CHG_AFTER_NOTIFIER & operator=(const CHG_AFTER_NOTIFIER & rvalue);
-    SMUX & smux;
-    UserPtr userPtr;
+class SMUX_SETTINGS
+{
+    public:
+        SMUX_SETTINGS();
+        virtual ~SMUX_SETTINGS() {}
+        const std::string & GetStrError() const { return errorStr; }
+        int ParseSettings(const ModuleSettings & s);
+
+        uint32_t GetIP() const { return ip; }
+        uint16_t GetPort() const { return port; }
+        const std::string GetPassword() const { return password; }
+
+    private:
+        mutable std::string errorStr;
+
+        uint32_t ip;
+        uint16_t port;
+        std::string password;
 };
 //-----------------------------------------------------------------------------
-class SMUX : public STG::Plugin {
-public:
-    SMUX();
-    virtual ~SMUX();
-
-    void SetUsers(STG::Users * u) { users = u; }
-    void SetTariffs(STG::Tariffs * t) { tariffs = t; }
-    void SetAdmins(STG::Admins * a) { admins = a; }
-    void SetServices(STG::Services * s) { services = s; }
-    void SetTraffcounter(STG::TraffCounter * tc) { traffcounter = tc; }
-    void SetCorporations(STG::Corporations * c) { corporations = c; }
-    void SetSettings(const STG::ModuleSettings & s) { settings = s; }
-    int ParseSettings();
-
-    int Start();
-    int Stop();
-    int Reload(const STG::ModuleSettings & ms);
-    bool IsRunning() { return m_thread.joinable() && !stopped; }
-
-    const std::string & GetStrError() const { return errorStr; }
-    std::string GetVersion() const { return "Stg SMUX Plugin 1.1"; }
-    uint16_t GetStartPosition() const { return 10; }
-    uint16_t GetStopPosition() const { return 10; }
-
-    bool UpdateTables();
-
-    void SetNotifier(UserPtr userPtr);
-    void UnsetNotifier(UserPtr userPtr);
-
-private:
-    SMUX(const SMUX & rvalue);
-    SMUX & operator=(const SMUX & rvalue);
-
-    void Run(std::stop_token token);
-    bool PrepareNet();
-    bool Reconnect();
-
-    bool DispatchPDUs(const SMUX_PDUs_t * pdus);
-
-    bool CloseHandler(const SMUX_PDUs_t * pdus);
-    bool RegisterResponseHandler(const SMUX_PDUs_t * pdus);
-    bool PDUsRequestHandler(const SMUX_PDUs_t * pdus);
-    bool CommitOrRollbackHandler(const SMUX_PDUs_t * pdus);
-
-    bool GetRequestHandler(const PDUs_t * pdus);
-    bool GetNextRequestHandler(const PDUs_t * pdus);
-    bool SetRequestHandler(const PDUs_t * pdus);
-
-    void SetNotifiers();
-    void ResetNotifiers();
-
-    STG::Users * users;
-    STG::Tariffs * tariffs;
-    STG::Admins * admins;
-    STG::Services * services;
-    STG::Corporations * corporations;
-    STG::TraffCounter * traffcounter;
-
-    mutable std::string errorStr;
-    SMUX_SETTINGS smuxSettings;
-    STG::ModuleSettings settings;
-
-    std::jthread m_thread;
-    std::mutex m_mutex;
-    bool stopped;
-    bool needReconnect;
-
-    time_t lastReconnectTry;
-    unsigned reconnectTimeout;
-
-    int sock;
-
-    SMUXHandlers smuxHandlers;
-    PDUsHandlers pdusHandlers;
-    Sensors sensors;
-    Tables tables;
-
-    STG::ScopedConnection m_onAddUserConn;
-    STG::ScopedConnection m_onDelUserConn;
-    STG::ScopedConnection m_onAddTariffConn;
-    STG::ScopedConnection m_onDelTariffConn;
-
-    std::list<CHG_AFTER_NOTIFIER> notifiers;
-
-    STG::PluginLogger logger;
+class SMUX : public Plugin
+{
+    public:
+        SMUX();
+        virtual ~SMUX();
+
+        void SetUsers(Users * u) { users = u; }
+        void SetTariffs(Tariffs * t) { tariffs = t; }
+        void SetAdmins(Admins * a) { admins = a; }
+        void SetServices(Services * s) { services = s; }
+        void SetTraffcounter(TraffCounter * tc) { traffcounter = tc; }
+        void SetCorporations(Corporations * c) { corporations = c; }
+        void SetSettings(const ModuleSettings & s) { settings = s; }
+        int ParseSettings();
+
+        int Start();
+        int Stop();
+        int Reload(const ModuleSettings & ms);
+        bool IsRunning() { return m_thread.joinable() && !stopped; }
+
+        const std::string & GetStrError() const { return errorStr; }
+        std::string GetVersion() const { return "Stg SMUX Plugin 1.1"; }
+        uint16_t GetStartPosition() const { return 10; }
+        uint16_t GetStopPosition() const { return 10; }
+
+        bool UpdateTables();
+
+        void SetNotifier(UserPtr userPtr);
+        void UnsetNotifier(UserPtr userPtr);
+
+    private:
+        SMUX(const SMUX & rvalue);
+        SMUX & operator=(const SMUX & rvalue);
+
+        void Run(std::stop_token token);
+        bool PrepareNet();
+        bool Reconnect();
+
+        bool DispatchPDUs(const SMUX_PDUs_t * pdus);
+
+        bool CloseHandler(const SMUX_PDUs_t * pdus);
+        bool RegisterResponseHandler(const SMUX_PDUs_t * pdus);
+        bool PDUsRequestHandler(const SMUX_PDUs_t * pdus);
+        bool CommitOrRollbackHandler(const SMUX_PDUs_t * pdus);
+
+        bool GetRequestHandler(const PDUs_t * pdus);
+        bool GetNextRequestHandler(const PDUs_t * pdus);
+        bool SetRequestHandler(const PDUs_t * pdus);
+
+        void SetNotifiers();
+        void ResetNotifiers();
+
+        Users * users;
+        Tariffs * tariffs;
+        Admins * admins;
+        Services * services;
+        Corporations * corporations;
+        TraffCounter * traffcounter;
+
+        mutable std::string errorStr;
+        SMUX_SETTINGS smuxSettings;
+        ModuleSettings settings;
+
+        std::jthread m_thread;
+        std::mutex m_mutex;
+        bool stopped;
+        bool needReconnect;
+
+        time_t lastReconnectTry;
+        unsigned reconnectTimeout;
+
+        int sock;
+
+        SMUXHandlers smuxHandlers;
+        PDUsHandlers pdusHandlers;
+        Sensors sensors;
+        Tables tables;
+
+        ScopedConnection m_onAddUserConn;
+        ScopedConnection m_onDelUserConn;
+        ScopedConnection m_onAddTariffConn;
+        ScopedConnection m_onDelTariffConn;
+
+        using ConnHolder = std::tuple<int, ScopedConnection>;
+        std::vector<ConnHolder> m_conns;
+
+        PluginLogger logger;
 };
-//-----------------------------------------------------------------------------
 
-inline
-void CHG_AFTER_NOTIFIER::notify(const std::string &, const std::string &)
-{
-smux.UpdateTables();
 }
index 44f2e5580ff8ec431655326b9cc57815d753a84a..a4227497a128e69cbcf27d3150975b5b952657a8 100644 (file)
@@ -51,8 +51,6 @@
 #define REMOVE_TIME  (31)
 
 using STG::TraffCounterImpl;
-using STG::TRF_IP_BEFORE;
-using STG::TRF_IP_AFTER;
 
 namespace AsyncPoolST = STG::AsyncPoolST;
 
@@ -82,8 +80,7 @@ m_onAddUserConn = users->onImplAdd([this](auto user){
     AsyncPoolST::enqueue([this, user](){ SetUserNotifiers(user); });
 });
 m_onDelUserConn = users->onImplDel([this](auto user){
-    AsyncPoolST::enqueue([this, user](){ UnSetUserNotifiers(user); });
-    AsyncPoolST::enqueue([this, user](){ DelUser(user->GetCurrIP()); });
+    AsyncPoolST::enqueue([this, user](){ UnSetUserNotifiers(user); DelUser(user->GetCurrIP()); });
 });
 }
 //-----------------------------------------------------------------------------
@@ -128,10 +125,7 @@ m_thread.request_stop();
 int h = users->OpenSearch();
 assert(h && "USERS::OpenSearch is always correct");
 
-UserImpl * u;
-while (users->SearchNext(h, &u) == 0)
-    UnSetUserNotifiers(u);
-users->CloseSearch(h);
+m_onIPConns.clear();
 
 //5 seconds to thread stops itself
 struct timespec ts = {0, 200000000};
@@ -446,47 +440,22 @@ while (pi.first != pi.second)
 ip2packets.erase(pi.first, pi.second);
 }
 //-----------------------------------------------------------------------------
-void TraffCounterImpl::SetUserNotifiers(UserImpl * user)
+void TraffCounterImpl::SetUserNotifiers(UserImpl* user)
 {
-// Adding user. Adding notifiers to user.
-TRF_IP_BEFORE ipBNotifier(*this, user);
-ipBeforeNotifiers.push_front(ipBNotifier);
-user->AddCurrIPBeforeNotifier(&(*ipBeforeNotifiers.begin()));
-
-TRF_IP_AFTER ipANotifier(*this, user);
-ipAfterNotifiers.push_front(ipANotifier);
-user->AddCurrIPAfterNotifier(&(*ipAfterNotifiers.begin()));
+    // Adding user. Adding notifiers to user.
+    m_onIPConns.emplace_back(
+        user->GetID(),
+        user->beforeCurrIPChange([this](auto oldVal, auto /*newVal*/){ beforeIPChange(oldVal); }),
+        user->afterCurrIPChange([this, user](auto /*oldVal*/, auto newVal){ afterIPChange(user, newVal); })
+    );
 }
 //-----------------------------------------------------------------------------
 void TraffCounterImpl::UnSetUserNotifiers(UserImpl * user)
 {
-// Removing user. Removing notifiers from user.
-std::list<TRF_IP_BEFORE>::iterator bi;
-std::list<TRF_IP_AFTER>::iterator ai;
-
-bi = ipBeforeNotifiers.begin();
-while (bi != ipBeforeNotifiers.end())
-    {
-    if (user->GetLogin() == bi->GetUser()->GetLogin())
-        {
-        user->DelCurrIPBeforeNotifier(&(*bi));
-        ipBeforeNotifiers.erase(bi);
-        break;
-        }
-    ++bi;
-    }
-
-ai = ipAfterNotifiers.begin();
-while (ai != ipAfterNotifiers.end())
-    {
-    if (user->GetLogin() == ai->GetUser()->GetLogin())
-        {
-        user->DelCurrIPAfterNotifier(&(*ai));
-        ipAfterNotifiers.erase(ai);
-        break;
-        }
-    ++ai;
-    }
+    // Removing user. Removing notifiers from user.
+    m_onIPConns.erase(std::remove_if(m_onIPConns.begin(), m_onIPConns.end(),
+                                     [user](const auto& cs){ return std::get<0>(cs) == user->GetID(); }),
+                      m_onIPConns.end());
 }
 //-----------------------------------------------------------------------------
 void TraffCounterImpl::DeterminateDir(const RawPacket & packet,
@@ -851,21 +820,21 @@ monitorDir = dir;
 monitoring = !monitorDir.empty();
 }
 //-----------------------------------------------------------------------------
-void TRF_IP_BEFORE::notify(const uint32_t & oldValue, const uint32_t &)
+void TraffCounterImpl::beforeIPChange(uint32_t oldVal)
 {
-// User changes his address. Remove old IP
-if (!oldValue)
-    return;
+    // User changes his address. Remove old IP
+    if (!oldVal)
+        return;
 
-AsyncPoolST::enqueue([this, oldValue](){ traffCnt.DelUser(oldValue); });
+    AsyncPoolST::enqueue([this, oldVal](){ DelUser(oldVal); });
 }
 //-----------------------------------------------------------------------------
-void TRF_IP_AFTER::notify(const uint32_t &, const uint32_t & newValue)
+void TraffCounterImpl::afterIPChange(UserImpl* user, uint32_t newVal)
 {
-// User changes his address. Add new IP
-if (!newValue)
-    return;
+    // User changes his address. Add new IP
+    if (!newVal)
+        return;
 
-AsyncPoolST::enqueue([this](){ traffCnt.AddUser(user); });
+    AsyncPoolST::enqueue([this, user](){ AddUser(user); });
 }
 //-----------------------------------------------------------------------------
index 474b669485afeb0234f5f4cc3ae475494bba7b6d..03c118dfb94a1c1c6bb9965a6b99c84f18e31761 100644 (file)
 #include "stg/logger.h"
 #include "stg/raw_ip_packet.h"
 #include "stg/subscriptions.h"
-#include "stg/notifer.h"
 #include "user_impl.h"
 
-#include <ctime>
 #include <list>
+#include <vector>
+#include <tuple>
 #include <map>
 #include <string>
 #include <mutex>
@@ -37,6 +37,7 @@
 #include <jthread.hpp>
 #pragma GCC diagnostic pop
 #include <cstdint>
+#include <ctime>
 
 #define PROTOMAX    (5)
 
@@ -81,58 +82,7 @@ struct PacketExtraData {
     uint32_t    lenD;               // Download length
 };
 //-----------------------------------------------------------------------------
-class TraffCounterImpl;
-//-----------------------------------------------------------------------------
-class TRF_IP_BEFORE: public PropertyNotifierBase<uint32_t> {
-public:
-                TRF_IP_BEFORE(TraffCounterImpl & t, UserImpl * u)
-                    : PropertyNotifierBase<uint32_t>(),
-                      traffCnt(t),
-                      user(u)
-                {}
-                TRF_IP_BEFORE(const TRF_IP_BEFORE & rvalue)
-                    : PropertyNotifierBase<uint32_t>(),
-                      traffCnt(rvalue.traffCnt),
-                      user(rvalue.user)
-                {}
-    void        notify(const uint32_t & oldValue, const uint32_t & newValue) override;
-    void        SetUser(UserImpl * u) { user = u; }
-    UserImpl * GetUser() const { return user; }
-
-private:
-    TRF_IP_BEFORE & operator=(const TRF_IP_BEFORE & rvalue);
-
-    TraffCounterImpl & traffCnt;
-    UserImpl * user;
-};
-//-----------------------------------------------------------------------------
-class TRF_IP_AFTER: public PropertyNotifierBase<uint32_t> {
-public:
-                TRF_IP_AFTER(TraffCounterImpl & t, UserImpl * u)
-                    : PropertyNotifierBase<uint32_t>(),
-                      traffCnt(t),
-                      user(u)
-                {}
-                TRF_IP_AFTER(const TRF_IP_AFTER & rvalue)
-                    : PropertyNotifierBase<uint32_t>(),
-                      traffCnt(rvalue.traffCnt),
-                      user(rvalue.user)
-                {}
-    void        notify(const uint32_t & oldValue, const uint32_t & newValue) override;
-    void        SetUser(UserImpl * u) { user = u; }
-    UserImpl * GetUser() const { return user; }
-private:
-    TRF_IP_AFTER & operator=(const TRF_IP_AFTER & rvalue);
-
-    TraffCounterImpl & traffCnt;
-    UserImpl * user;
-};
-
-using UserImplPtr = UserImpl*;
-//-----------------------------------------------------------------------------
 class TraffCounterImpl : public TraffCounter {
-    friend class TRF_IP_BEFORE;
-    friend class TRF_IP_AFTER;
     public:
         TraffCounterImpl(UsersImpl * users, const std::string & rulesFileName);
         ~TraffCounterImpl();
@@ -162,8 +112,8 @@ class TraffCounterImpl : public TraffCounter {
 
         void        AddUser(UserImpl * user);
         void        DelUser(uint32_t uip);
-        void        SetUserNotifiers(UserImpl * user);
-        void        UnSetUserNotifiers(UserImpl * user);
+        void        SetUserNotifiers(UserImpl* user);
+        void        UnSetUserNotifiers(UserImpl* user);
 
         typedef std::list<Rule>::iterator rule_iter;
 
@@ -197,8 +147,10 @@ class TraffCounterImpl : public TraffCounter {
         ScopedConnection m_onAddUserConn;
         ScopedConnection m_onDelUserConn;
 
-        std::list<TRF_IP_BEFORE> ipBeforeNotifiers;
-        std::list<TRF_IP_AFTER>  ipAfterNotifiers;
+        using OnIPConns = std::tuple<int, ScopedConnection, ScopedConnection>;
+        std::vector<OnIPConns> m_onIPConns;
+        void beforeIPChange(uint32_t oldVal);
+        void afterIPChange(UserImpl* user, uint32_t newVal);
 };
 
 }
index 60e801b98144c58c2fe3275cc9429a855d9f87f0..7116a11e0a97cf1e68029c16c19244e095832c71 100644 (file)
@@ -88,10 +88,6 @@ UserImpl::UserImpl(const Settings * s,
       WriteServLog(Logger::get()),
       lastScanMessages(0),
       id(0),
-      __connected(0),
-      connected(__connected),
-      __currIP(0),
-      currIP(__currIP),
       lastIPForDisconnect(0),
       pingTime(0),
       sysAdmin(a),
@@ -139,14 +135,9 @@ UserImpl::UserImpl(const Settings * s,
       userdata8(properties.userdata8),
       userdata9(properties.userdata9),
       sessionUploadModTime(stgTime),
-      sessionDownloadModTime(stgTime),
-      passiveNotifier(this),
-      disabledNotifier(this),
-      tariffNotifier(this),
-      cashNotifier(this),
-      ipNotifier(this)
+      sessionDownloadModTime(stgTime)
 {
-Init();
+    Init();
 }
 //-----------------------------------------------------------------------------
 void UserImpl::Init()
@@ -158,11 +149,11 @@ ips = UserIPs::parse("*");
 lastWriteStat = stgTime + random() % settings->GetStatWritePeriod();
 lastWriteDetailedStat = stgTime;
 
-properties.tariffName.AddBeforeNotifier(&tariffNotifier);
-properties.passive.AddBeforeNotifier(&passiveNotifier);
-properties.disabled.AddAfterNotifier(&disabledNotifier);
-properties.cash.AddBeforeNotifier(&cashNotifier);
-ips.AddAfterNotifier(&ipNotifier);
+m_beforePassiveConn = properties.passive.beforeChange([this](auto oldVal, auto newVal){ onPassiveChange(oldVal, newVal); });
+m_afterDisabledConn = properties.disabled.afterChange([this](auto oldVal, auto newVal){ onDisabledChange(oldVal, newVal); });
+m_beforeTariffConn = properties.tariffName.beforeChange([this](const auto& oldVal, const auto& newVal){ onTariffChange(oldVal, newVal); });
+m_beforeCashConn = properties.cash.beforeChange([this](auto oldVal, auto newVal){ onCashChange(oldVal, newVal); });
+m_afterIPConn = ips.afterChange([this](const auto& oldVal, const auto& newVal){ onIPChange(oldVal, newVal); });
 
 pthread_mutexattr_t attr;
 pthread_mutexattr_init(&attr);
@@ -177,10 +168,6 @@ UserImpl::UserImpl(const UserImpl & u)
       lastScanMessages(0),
       login(u.login),
       id(u.id),
-      __connected(0),
-      connected(__connected),
-      __currIP(u.__currIP),
-      currIP(__currIP),
       lastIPForDisconnect(0),
       pingTime(u.pingTime),
       sysAdmin(u.sysAdmin),
@@ -233,36 +220,27 @@ UserImpl::UserImpl(const UserImpl & u)
       sessionUpload(),
       sessionDownload(),
       sessionUploadModTime(stgTime),
-      sessionDownloadModTime(stgTime),
-      passiveNotifier(this),
-      disabledNotifier(this),
-      tariffNotifier(this),
-      cashNotifier(this),
-      ipNotifier(this)
+      sessionDownloadModTime(stgTime)
 {
-if (&u == this)
-    return;
+    if (&u == this)
+        return;
 
-properties.tariffName.AddBeforeNotifier(&tariffNotifier);
-properties.passive.AddBeforeNotifier(&passiveNotifier);
-properties.disabled.AddAfterNotifier(&disabledNotifier);
-properties.cash.AddBeforeNotifier(&cashNotifier);
-ips.AddAfterNotifier(&ipNotifier);
+    m_beforePassiveConn = properties.passive.beforeChange([this](auto oldVal, auto newVal){ onPassiveChange(oldVal, newVal); });
+    m_afterDisabledConn = properties.disabled.afterChange([this](auto oldVal, auto newVal){ onDisabledChange(oldVal, newVal); });
+    m_beforeTariffConn = properties.tariffName.beforeChange([this](const auto& oldVal, const auto& newVal){ onTariffChange(oldVal, newVal); });
+    m_beforeCashConn = properties.cash.beforeChange([this](auto oldVal, auto newVal){ onCashChange(oldVal, newVal); });
+    m_afterIPConn = ips.afterChange([this](const auto& oldVal, const auto& newVal){ onIPChange(oldVal, newVal); });
 
-properties.SetProperties(u.properties);
+    properties.SetProperties(u.properties);
 
-pthread_mutexattr_t attr;
-pthread_mutexattr_init(&attr);
-pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
-pthread_mutex_init(&mutex, &attr);
+    pthread_mutexattr_t attr;
+    pthread_mutexattr_init(&attr);
+    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+    pthread_mutex_init(&mutex, &attr);
 }
 //-----------------------------------------------------------------------------
 UserImpl::~UserImpl()
 {
-properties.tariffName.DelBeforeNotifier(&tariffNotifier);
-properties.passive.DelBeforeNotifier(&passiveNotifier);
-properties.disabled.DelAfterNotifier(&disabledNotifier);
-properties.cash.DelBeforeNotifier(&cashNotifier);
 pthread_mutex_destroy(&mutex);
 }
 //-----------------------------------------------------------------------------
@@ -428,7 +406,7 @@ dirsFromBits(enabledDirs, dirs);
 
 if (!authorizedBy.empty())
     {
-    if (currIP != ip)
+    if (m_currIP != ip)
         {
         // We are already authorized, but with different IP address
         errorStr = "User " + login + " already authorized with IP address " + inet_ntostring(ip);
@@ -458,8 +436,8 @@ else
 
     if (ips.ConstData().find(ip))
         {
-        currIP = ip;
-        lastIPForDisconnect = currIP;
+        m_currIP = ip;
+        lastIPForDisconnect = m_currIP;
         }
     else
         {
@@ -492,9 +470,9 @@ authorizedModificationTime = stgTime;
 if (authorizedBy.empty())
     {
     lastDisconnectReason = reason;
-    lastIPForDisconnect = currIP;
-    currIP = 0; // DelUser in traffcounter
-    if (connected)
+    lastIPForDisconnect = m_currIP;
+    m_currIP = 0; // DelUser in traffcounter
+    if (m_connected)
         Disconnect(false, "not authorized");
     return;
     }
@@ -536,7 +514,7 @@ if (!fakeConnect)
                   "%s \"%s\" \"%s\" \"%f\" \"%d\" \"%s\"",
                   scriptOnConnect.c_str(),
                   login.c_str(),
-                  inet_ntostring(currIP).c_str(),
+                  inet_ntostring(m_currIP).c_str(),
                   cash.ConstData(),
                   id,
                   dirs.c_str());
@@ -555,17 +533,17 @@ if (!fakeConnect)
         WriteServLog("Script %s cannot be executed. File not found.", scriptOnConnect.c_str());
         }
 
-    connected = true;
+    m_connected = true;
     }
 
-if (!settings->GetDisableSessionLog() && store->WriteUserConnect(login, currIP))
+if (!settings->GetDisableSessionLog() && store->WriteUserConnect(login, m_currIP))
     {
     WriteServLog("Cannot write connect for user %s.", login.c_str());
     WriteServLog("%s", store->GetStrError().c_str());
     }
 
 if (!fakeConnect)
-    lastIPForDisconnect = currIP;
+    lastIPForDisconnect = m_currIP;
 }
 //-----------------------------------------------------------------------------
 void UserImpl::Disconnect(bool fakeDisconnect, const std::string & reason)
@@ -615,7 +593,7 @@ if (!fakeDisconnect)
         WriteServLog("Script OnDisconnect cannot be executed. File not found.");
         }
 
-    connected = false;
+    m_connected = false;
     }
 
 std::string reasonMessage(reason);
@@ -665,13 +643,13 @@ if (passive.ConstData()
 
 if (!authorizedBy.empty())
     {
-    if (connected)
+    if (m_connected)
         properties.Stat().lastActivityTime = stgTime;
 
-    if (!connected && IsInetable())
+    if (!m_connected && IsInetable())
         Connect();
 
-    if (connected && !IsInetable())
+    if (m_connected && !IsInetable())
         {
         if (disabled)
             Disconnect(false, "disabled");
@@ -689,7 +667,7 @@ if (!authorizedBy.empty())
     }
 else
     {
-    if (connected)
+    if (m_connected)
         Disconnect(false, "not authorized");
     }
 
@@ -734,7 +712,7 @@ void UserImpl::AddTraffStatU(int dir, uint32_t ip, uint32_t len)
 {
 STG_LOCKER lock(&mutex);
 
-if (!connected || tariff == NULL)
+if (!m_connected || tariff == NULL)
     return;
 
 double cost = 0;
@@ -827,7 +805,7 @@ void UserImpl::AddTraffStatD(int dir, uint32_t ip, uint32_t len)
 {
 STG_LOCKER lock(&mutex);
 
-if (!connected || tariff == NULL)
+if (!m_connected || tariff == NULL)
     return;
 
 double cost = 0;
@@ -911,54 +889,6 @@ else
     }
 }
 //-----------------------------------------------------------------------------
-void UserImpl::AddCurrIPBeforeNotifier(CURR_IP_NOTIFIER * notifier)
-{
-STG_LOCKER lock(&mutex);
-currIP.AddBeforeNotifier(notifier);
-}
-//-----------------------------------------------------------------------------
-void UserImpl::DelCurrIPBeforeNotifier(const CURR_IP_NOTIFIER * notifier)
-{
-STG_LOCKER lock(&mutex);
-currIP.DelBeforeNotifier(notifier);
-}
-//-----------------------------------------------------------------------------
-void UserImpl::AddCurrIPAfterNotifier(CURR_IP_NOTIFIER * notifier)
-{
-STG_LOCKER lock(&mutex);
-currIP.AddAfterNotifier(notifier);
-}
-//-----------------------------------------------------------------------------
-void UserImpl::DelCurrIPAfterNotifier(const CURR_IP_NOTIFIER * notifier)
-{
-STG_LOCKER lock(&mutex);
-currIP.DelAfterNotifier(notifier);
-}
-//-----------------------------------------------------------------------------
-void UserImpl::AddConnectedBeforeNotifier(CONNECTED_NOTIFIER * notifier)
-{
-STG_LOCKER lock(&mutex);
-connected.AddBeforeNotifier(notifier);
-}
-//-----------------------------------------------------------------------------
-void UserImpl::DelConnectedBeforeNotifier(const CONNECTED_NOTIFIER * notifier)
-{
-STG_LOCKER lock(&mutex);
-connected.DelBeforeNotifier(notifier);
-}
-//-----------------------------------------------------------------------------
-void UserImpl::AddConnectedAfterNotifier(CONNECTED_NOTIFIER * notifier)
-{
-STG_LOCKER lock(&mutex);
-connected.AddAfterNotifier(notifier);
-}
-//-----------------------------------------------------------------------------
-void UserImpl::DelConnectedAfterNotifier(const CONNECTED_NOTIFIER * notifier)
-{
-STG_LOCKER lock(&mutex);
-connected.DelAfterNotifier(notifier);
-}
-//-----------------------------------------------------------------------------
 void UserImpl::OnAdd()
 {
 STG_LOCKER lock(&mutex);
@@ -1087,7 +1017,7 @@ void UserImpl::MidnightResetSessionStat()
 {
 STG_LOCKER lock(&mutex);
 
-if (connected)
+if (m_connected)
     {
     Disconnect(true, "fake");
     Connect(true);
@@ -1098,7 +1028,7 @@ void UserImpl::ProcessNewMonth()
 {
 STG_LOCKER lock(&mutex);
 //  Reset traff
-if (connected)
+if (m_connected)
     Disconnect(true, "fake");
 
 WriteMonthStat();
@@ -1106,7 +1036,7 @@ WriteMonthStat();
 properties.Stat().monthUp.reset();
 properties.Stat().monthDown.reset();
 
-if (connected)
+if (m_connected)
     Connect(true);
 
 //  Set new tariff
@@ -1399,7 +1329,7 @@ int ret = -1;
 std::set<const Auth*>::iterator it(authorizedBy.begin());
 while (it != authorizedBy.end())
     {
-    if (!(*it++)->SendMessage(msg, currIP))
+    if (!(*it++)->SendMessage(msg, m_currIP))
         ret = 0;
     }
 if (!ret)
@@ -1479,7 +1409,7 @@ std::string UserImpl::GetParamValue(const std::string & name) const
         return stream.str();
         }
     if (lowerName == "login")       return login;
-    if (lowerName == "currip")      return currIP.ToString();
+    if (lowerName == "currip")      return m_currIP.ToString();
     if (lowerName == "enableddirs") return GetEnabledDirs();
     if (lowerName == "tariff")      return properties.tariffName;
     if (properties.Exists(lowerName))
@@ -1493,51 +1423,52 @@ std::string UserImpl::GetParamValue(const std::string & name) const
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-void STG::CHG_PASSIVE_NOTIFIER::notify(const int & oldPassive, const int & newPassive)
+void UserImpl::onPassiveChange(int oldVal, int newVal)
 {
-if (newPassive && !oldPassive && user->tariff != NULL)
-    user->properties.cash.Set(user->cash - user->tariff->GetPassiveCost(),
-                            *user->sysAdmin,
-                            user->login,
-                            *user->store,
+    if (newVal && !oldVal && tariff != NULL)
+        properties.cash.Set(cash - tariff->GetPassiveCost(),
+                            *sysAdmin,
+                            login,
+                            *store,
                             "Freeze");
 }
 //-----------------------------------------------------------------------------
-void STG::CHG_DISABLED_NOTIFIER::notify(const int & oldValue, const int & newValue)
+void UserImpl::onDisabledChange(int oldVal, int newVal)
 {
-if (oldValue && !newValue && user->GetConnected())
-    user->Disconnect(false, "disabled");
-else if (!oldValue && newValue && user->IsInetable())
-    user->Connect(false);
+    if (oldVal && !newVal && GetConnected())
+        Disconnect(false, "disabled");
+    else if (!oldVal && newVal && IsInetable())
+        Connect(false);
 }
 //-----------------------------------------------------------------------------
-void STG::CHG_TARIFF_NOTIFIER::notify(const std::string &, const std::string & newTariff)
+void UserImpl::onTariffChange(const std::string& /*oldVal*/, const std::string& newVal)
 {
-STG_LOCKER lock(&user->mutex);
-if (user->settings->GetReconnectOnTariffChange() && user->connected)
-    user->Disconnect(false, "Change tariff");
-user->tariff = user->tariffs->FindByName(newTariff);
-if (user->settings->GetReconnectOnTariffChange() &&
-    !user->authorizedBy.empty() &&
-    user->IsInetable())
+    STG_LOCKER lock(&mutex);
+    if (settings->GetReconnectOnTariffChange() && m_connected)
+        Disconnect(false, "Change tariff");
+    tariff = tariffs->FindByName(newVal);
+    if (settings->GetReconnectOnTariffChange() &&
+        !authorizedBy.empty() &&
+        IsInetable())
     {
-    // This notifier gets called *before* changing the tariff, and in Connect we want to see new tariff name.
-    user->properties.Conf().tariffName = newTariff;
-    user->Connect(false);
+        // This notifier gets called *before* changing the tariff, and in Connect we want to see new tariff name.
+        properties.Conf().tariffName = newVal;
+        Connect(false);
     }
 }
 //-----------------------------------------------------------------------------
-void STG::CHG_CASH_NOTIFIER::notify(const double & oldCash, const double & newCash)
+void UserImpl::onCashChange(double oldVal, double newVal)
 {
-user->lastCashAddTime = *const_cast<time_t *>(&stgTime);
-user->lastCashAdd = newCash - oldCash;
+    time_t now = stgTime;
+    lastCashAddTime = now;
+    lastCashAdd = newVal - oldVal;
 }
 //-----------------------------------------------------------------------------
-void STG::CHG_IPS_NOTIFIER::notify(const UserIPs & from, const UserIPs & to)
+void UserImpl::onIPChange(const UserIPs& oldVal, const UserIPs& newVal)
 {
-printfd(__FILE__, "Change IP from '%s' to '%s'\n", from.toString().c_str(), to.toString().c_str());
-if (user->connected)
-    user->Disconnect(false, "Change IP");
-if (!user->authorizedBy.empty() && user->IsInetable())
-    user->Connect(false);
+    printfd(__FILE__, "Change IP from '%s' to '%s'\n", oldVal.toString().c_str(), newVal.toString().c_str());
+    if (m_connected)
+        Disconnect(false, "Change IP");
+    if (!authorizedBy.empty() && IsInetable())
+        Connect(false);
 }
index 4beeb2e209247475bdc2b18a8465dae70e523460..ff7e28a062e52f87def05bd1e5cdf84ba3a05dab 100644 (file)
@@ -51,57 +51,8 @@ struct Settings;
 class SettingsImpl;
 #endif
 //-----------------------------------------------------------------------------
-class CHG_PASSIVE_NOTIFIER : public PropertyNotifierBase<int> {
-    public:
-        explicit CHG_PASSIVE_NOTIFIER(UserImpl * u) : user(u) {}
-        void notify(const int & oldPassive, const int & newPassive) override;
-
-    private:
-        UserImpl * user;
-};
-//-----------------------------------------------------------------------------
-class CHG_DISABLED_NOTIFIER : public PropertyNotifierBase<int> {
-public:
-    explicit CHG_DISABLED_NOTIFIER(UserImpl * u) : user(u) {}
-    void notify(const int & oldValue, const int & newValue) override;
-
-private:
-    UserImpl * user;
-};
-//-----------------------------------------------------------------------------
-class CHG_TARIFF_NOTIFIER : public PropertyNotifierBase<std::string> {
-public:
-    explicit CHG_TARIFF_NOTIFIER(UserImpl * u) : user(u) {}
-    void notify(const std::string & oldTariff, const std::string & newTariff) override;
-
-private:
-    UserImpl * user;
-};
-//-----------------------------------------------------------------------------
-class CHG_CASH_NOTIFIER : public PropertyNotifierBase<double> {
-public:
-    explicit CHG_CASH_NOTIFIER(UserImpl * u) : user(u) {}
-    void notify(const double & oldCash, const double & newCash) override;
-
-private:
-    UserImpl * user;
-};
-//-----------------------------------------------------------------------------
-class CHG_IPS_NOTIFIER : public PropertyNotifierBase<UserIPs> {
-public:
-    explicit CHG_IPS_NOTIFIER(UserImpl * u) : user(u) {}
-    void notify(const UserIPs & oldIPs, const UserIPs & newIPs) override;
-
-private:
-    UserImpl * user;
-};
-//-----------------------------------------------------------------------------
-class UserImpl : public User {
-    friend class CHG_PASSIVE_NOTIFIER;
-    friend class CHG_DISABLED_NOTIFIER;
-    friend class CHG_TARIFF_NOTIFIER;
-    friend class CHG_CASH_NOTIFIER;
-    friend class CHG_IPS_NOTIFIER;
+class UserImpl : public User
+{
     public:
 #ifdef USE_ABSTRACT_SETTINGS
         using Settings = STG::Settings;
@@ -126,21 +77,6 @@ class UserImpl : public User {
         const std::string & GetLogin() const override { return login; }
         void            SetLogin(std::string const & l);
 
-        uint32_t        GetCurrIP() const override{ return currIP; }
-        time_t          GetCurrIPModificationTime() const override { return currIP.ModificationTime(); }
-
-        void            AddCurrIPBeforeNotifier(CURR_IP_NOTIFIER * notifier) override;
-        void            DelCurrIPBeforeNotifier(const CURR_IP_NOTIFIER * notifier) override;
-
-        void            AddCurrIPAfterNotifier(CURR_IP_NOTIFIER * notifier) override;
-        void            DelCurrIPAfterNotifier(const CURR_IP_NOTIFIER * notifier) override;
-
-        void            AddConnectedBeforeNotifier(CONNECTED_NOTIFIER * notifier) override;
-        void            DelConnectedBeforeNotifier(const CONNECTED_NOTIFIER * notifier) override;
-
-        void            AddConnectedAfterNotifier(CONNECTED_NOTIFIER * notifier) override;
-        void            DelConnectedAfterNotifier(const CONNECTED_NOTIFIER * notifier) override;
-
         int             GetID() const override { return id; }
 
         double          GetPassiveTimePart() const override;
@@ -165,8 +101,6 @@ class UserImpl : public User {
         time_t GetSessionUploadModificationTime() const override { return sessionUploadModTime; }
         time_t GetSessionDownloadModificationTime() const override { return sessionDownloadModTime; }
 
-        bool            GetConnected() const override { return connected; }
-        time_t          GetConnectedModificationTime() const override { return connected.ModificationTime(); }
         const std::string & GetLastDisconnectReason() const override { return lastDisconnectReason; }
         int             GetAuthorized() const override { return static_cast<int>(authorizedBy.size()); }
         time_t          GetAuthorizedModificationTime() const override { return authorizedModificationTime; }
@@ -230,14 +164,9 @@ class UserImpl : public User {
 
         std::string     login;
         int             id;
-        bool            __connected;
-        UserProperty<bool> connected;
 
         bool            enabledDirs[DIR_NUM];
 
-        uint32_t        __currIP; // Current user's ip
-        UserProperty<uint32_t> currIP;
-
         uint32_t        lastIPForDisconnect; // User's ip after unauth but before disconnect
         std::string     lastDisconnectReason;
 
@@ -309,11 +238,20 @@ class UserImpl : public User {
         time_t                   sessionUploadModTime;
         time_t                   sessionDownloadModTime;
 
-        CHG_PASSIVE_NOTIFIER     passiveNotifier;
-        CHG_DISABLED_NOTIFIER    disabledNotifier;
-        CHG_TARIFF_NOTIFIER      tariffNotifier;
-        CHG_CASH_NOTIFIER        cashNotifier;
-        CHG_IPS_NOTIFIER         ipNotifier;
+        ScopedConnection m_beforePassiveConn;
+        void onPassiveChange(int oldVal, int newVal);
+
+        ScopedConnection m_afterDisabledConn;
+        void onDisabledChange(int oldVal, int newVal);
+
+        ScopedConnection m_beforeTariffConn;
+        void onTariffChange(const std::string& oldVal, const std::string& newVal);
+
+        ScopedConnection m_beforeCashConn;
+        void onCashChange(double oldVal, double newVal);
+
+        ScopedConnection m_afterIPConn;
+        void onIPChange(const UserIPs& oldVal, const UserIPs& newVal);
 
         mutable pthread_mutex_t  mutex;
 
index 7b6f900adc1209d345289084034a65dc8d0890c6..d84dcb6e3a34ad7173ea37c07c566247ad64f1dd 100644 (file)
 
 #pragma once
 
-#include <pthread.h>
+#include "settings_impl.h"
+#include "user_impl.h"
+#include "stg/store.h"
+#include "stg/users.h"
+#include "stg/user.h"
+#include "stg/tariffs.h"
+#include "stg/logger.h"
+#include "stg/noncopyable.h"
 
 #include <string>
 #include <map>
 #include <ctime>
 #include <cstdint>
 
-#include "stg/store.h"
-#include "stg/users.h"
-#include "stg/user.h"
-#include "stg/tariffs.h"
-#include "stg/logger.h"
-#include "stg/notifer.h"
-#include "stg/noncopyable.h"
-#include "settings_impl.h"
-#include "user_impl.h"
-
 namespace STG
 {
 
index c47bc1fdb2ee15b2cea5927650f6aec98a662fa9..856c85d33b718d8be98c82cab1cbb48a861e709e 100644 (file)
@@ -24,19 +24,19 @@ volatile time_t stgTime = 0;
 namespace
 {
 
-class AfterConnectedNotifier : public STG::PropertyNotifierBase<bool>
+class ConnectCtr
 {
     public:
-        AfterConnectedNotifier()
+        ConnectCtr()
             : m_connects(0),
               m_disconnects(0)
         {}
 
-        void notify(const bool& oldValue, const bool& newValue) override
+        void update(bool isConnect)
         {
-            if (!oldValue && newValue)
+            if (isConnect)
                 ++m_connects;
-            if (oldValue && !newValue)
+            else
                 ++m_disconnects;
         }
 
@@ -77,9 +77,8 @@ BOOST_AUTO_TEST_CASE(NormalBehavior)
     TestServices services;
     STG::UserImpl user(&settings, &store, &tariffs, &admin, &users, services);
 
-    AfterConnectedNotifier connectionNotifier;
-
-    user.AddConnectedAfterNotifier(&connectionNotifier);
+    ConnectCtr ctr;
+    STG::ScopedConnection conn = user.afterConnectedChange([&ctr](auto, auto newVal){ ctr.update(newVal); });
 
     STG::UserProperty<std::string> & tariffName = user.GetProperties().tariffName;
     STG::UserProperty<STG::UserIPs> & ips = user.GetProperties().ips;
@@ -87,8 +86,8 @@ BOOST_AUTO_TEST_CASE(NormalBehavior)
     ips = STG::UserIPs::parse("*");
 
     BOOST_CHECK_EQUAL(user.GetConnected(), false);
-    BOOST_CHECK_EQUAL(connectionNotifier.connects(), static_cast<size_t>(0));
-    BOOST_CHECK_EQUAL(connectionNotifier.disconnects(), static_cast<size_t>(0));
+    BOOST_CHECK_EQUAL(ctr.connects(), static_cast<size_t>(0));
+    BOOST_CHECK_EQUAL(ctr.disconnects(), static_cast<size_t>(0));
 
     BOOST_CHECK_EQUAL(user.GetProperties().tariffName.ConstData(), NO_TARIFF_NAME);
 
@@ -98,8 +97,8 @@ BOOST_AUTO_TEST_CASE(NormalBehavior)
     BOOST_CHECK_EQUAL(user.IsAuthorizedBy(&auth), true);
 
     BOOST_CHECK_EQUAL(user.GetConnected(), true);
-    BOOST_CHECK_EQUAL(connectionNotifier.connects(), static_cast<size_t>(1));
-    BOOST_CHECK_EQUAL(connectionNotifier.disconnects(), static_cast<size_t>(0));
+    BOOST_CHECK_EQUAL(ctr.connects(), static_cast<size_t>(1));
+    BOOST_CHECK_EQUAL(ctr.disconnects(), static_cast<size_t>(0));
 
     tariffName = "test";
     BOOST_CHECK_EQUAL(user.GetProperties().tariffName.ConstData(), "test");
@@ -107,8 +106,8 @@ BOOST_AUTO_TEST_CASE(NormalBehavior)
     BOOST_CHECK_EQUAL(user.IsAuthorizedBy(&auth), true);
 
     BOOST_CHECK_EQUAL(user.GetConnected(), true);
-    BOOST_CHECK_EQUAL(connectionNotifier.connects(), static_cast<size_t>(1));
-    BOOST_CHECK_EQUAL(connectionNotifier.disconnects(), static_cast<size_t>(0));
+    BOOST_CHECK_EQUAL(ctr.connects(), static_cast<size_t>(1));
+    BOOST_CHECK_EQUAL(ctr.disconnects(), static_cast<size_t>(0));
 }
 
 BOOST_AUTO_TEST_CASE(Reconnect)
@@ -130,9 +129,8 @@ BOOST_AUTO_TEST_CASE(Reconnect)
     TestServices services;
     STG::UserImpl user(&settings, &store, &tariffs, &admin, &users, services);
 
-    AfterConnectedNotifier connectionNotifier;
-
-    user.AddConnectedAfterNotifier(&connectionNotifier);
+    ConnectCtr ctr;
+    STG::ScopedConnection conn = user.afterConnectedChange([&ctr](auto, auto newVal){ ctr.update(newVal); });
 
     STG::UserProperty<std::string> & tariffName = user.GetProperties().tariffName;
     STG::UserProperty<STG::UserIPs> & ips = user.GetProperties().ips;
@@ -140,8 +138,8 @@ BOOST_AUTO_TEST_CASE(Reconnect)
     ips = STG::UserIPs::parse("*");
 
     BOOST_CHECK_EQUAL(user.GetConnected(), false);
-    BOOST_CHECK_EQUAL(connectionNotifier.connects(), static_cast<size_t>(0));
-    BOOST_CHECK_EQUAL(connectionNotifier.disconnects(), static_cast<size_t>(0));
+    BOOST_CHECK_EQUAL(ctr.connects(), static_cast<size_t>(0));
+    BOOST_CHECK_EQUAL(ctr.disconnects(), static_cast<size_t>(0));
 
     BOOST_CHECK_EQUAL(user.GetProperties().tariffName.ConstData(), NO_TARIFF_NAME);
 
@@ -151,8 +149,8 @@ BOOST_AUTO_TEST_CASE(Reconnect)
     BOOST_CHECK_EQUAL(user.IsAuthorizedBy(&auth), true);
 
     BOOST_CHECK_EQUAL(user.GetConnected(), true);
-    BOOST_CHECK_EQUAL(connectionNotifier.connects(), static_cast<size_t>(1));
-    BOOST_CHECK_EQUAL(connectionNotifier.disconnects(), static_cast<size_t>(0));
+    BOOST_CHECK_EQUAL(ctr.connects(), static_cast<size_t>(1));
+    BOOST_CHECK_EQUAL(ctr.disconnects(), static_cast<size_t>(0));
 
     tariffName = "test";
     BOOST_CHECK_EQUAL(user.GetProperties().tariffName.ConstData(), "test");
@@ -160,8 +158,8 @@ BOOST_AUTO_TEST_CASE(Reconnect)
     BOOST_CHECK_EQUAL(user.IsAuthorizedBy(&auth), true);
 
     BOOST_CHECK_EQUAL(user.GetConnected(), true);
-    BOOST_CHECK_EQUAL(connectionNotifier.connects(), static_cast<size_t>(2));
-    BOOST_CHECK_EQUAL(connectionNotifier.disconnects(), static_cast<size_t>(1));
+    BOOST_CHECK_EQUAL(ctr.connects(), static_cast<size_t>(2));
+    BOOST_CHECK_EQUAL(ctr.disconnects(), static_cast<size_t>(1));
 }
 
 BOOST_AUTO_TEST_SUITE_END()