+++ /dev/null
-#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>;
-
-}
* 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)
#include <cstdint>
-namespace RS
+namespace STG::RS
{
struct PACKET_HEADER
} __attribute__((__packed__)); // 992 bytes, 124 blocks
} // namespace RS
-
-#endif
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
#pragma once
-#include "notifer.h"
#include "message.h"
+#include "user_property.h"
#include <vector>
#include <string>
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;
};
}
#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"
namespace STG
{
//-----------------------------------------------------------------------------
-struct UserPropertyBase {
+struct UserPropertyBase
+{
virtual ~UserPropertyBase() = default;
virtual std::string ToString() const = 0;
};
using Registry = std::map<std::string, UserPropertyBase*>;
//-----------------------------------------------------------------------------
template<typename T>
-class UserProperty : public UserPropertyBase {
+class UserProperty : public UserPropertyBase
+{
public:
explicit UserProperty(T& val);
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;
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,
const Settings& settings;
};
//-----------------------------------------------------------------------------
-class UserProperties {
+class UserProperties
+{
/*
В этом месте важен порядок следования приватной и открытой частей.
Это связано с тем, что часть которая находится в публичной секции
inline
UserProperty<T>::UserProperty(T& val)
: value(val),
- modificationTime(time(NULL)),
- beforeNotifiers(),
- afterNotifiers()
+ modificationTime(time(NULL))
{
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
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>
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>
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);
//-----------------------------------------------------------------------------
bool LISTENER::GetParams(char * buffer, UserData & data)
{
-RS::PACKET_TAIL packetTail;
+STG::RS::PACKET_TAIL packetTail;
DecryptString(&packetTail, buffer, sizeof(packetTail), &ctxS);
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;
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();
#include <unistd.h>
+using STG::AUTH_AO;
+
extern "C" STG::Plugin* GetPlugin()
{
static AUTH_AO plugin;
AUTH_AO::AUTH_AO()
: users(NULL),
isRunning(false),
- logger(STG::PluginLogger::get("auth_ao"))
+ logger(PluginLogger::get("auth_ao"))
{
}
//-----------------------------------------------------------------------------
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()
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);
-}
-//-----------------------------------------------------------------------------
#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>;
-
-};
+}
#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"
#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);
PING::PING()
: users(nullptr),
isRunning(false),
- logger(STG::PluginLogger::get("ping"))
+ logger(PluginLogger::get("ping"))
{
}
//-----------------------------------------------------------------------------
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();
//-----------------------------------------------------------------------------
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()
}
}
//-----------------------------------------------------------------------------
-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);
}
#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"
#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;
};
+
+}
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;
{
}
//-----------------------------------------------------------------------------
-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";
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;
}
isRunning(false),
users(nullptr),
sock(0),
- logger(STG::PluginLogger::get("rscript"))
+ logger(PluginLogger::get("rscript"))
{
}
//-----------------------------------------------------------------------------
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();
return 0;
}
//-----------------------------------------------------------------------------
-int REMOTE_SCRIPT::Reload(const STG::ModuleSettings & /*ms*/)
+int REMOTE_SCRIPT::Reload(const ModuleSettings & /*ms*/)
{
NRMapParser nrMapParser;
//-----------------------------------------------------------------------------
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());
}
//-----------------------------------------------------------------------------
}*/
}
//-----------------------------------------------------------------------------
-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
#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"
{
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),
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
+}
* 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
#include "utils.h"
#include "smux.h"
+using STG::SMUX;
+
#ifdef SMUX_DEBUG
bool SMUX::CloseHandler(const SMUX_PDUs_t * pdus)
{
#include "smux.h"
#include "utils.h"
+using STG::SMUX;
+using STG::SMUX_SETTINGS;
+
namespace
{
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";
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;
return 0;
}
-int SMUX::Reload(const STG::ModuleSettings & /*ms*/)
+int SMUX::Reload(const ModuleSettings & /*ms*/)
{
if (Stop() != 0)
return -1;
void SMUX::SetNotifier(UserPtr userPtr)
{
-notifiers.emplace_back(*this, userPtr);
-userPtr->GetProperties().tariffName.AddAfterNotifier(¬ifiers.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()
UpdateTables();
});
-auto updateTables = [this](const STG::TariffData&){ UpdateTables(); };
+auto updateTables = [this](const TariffData&){ UpdateTables(); };
m_onAddTariffConn = tariffs->onAdd(updateTables);
m_onDelTariffConn = tariffs->onDel(updateTables);
}
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();
}
#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"
struct Services;
struct Corporations;
struct TraffCounter;
-}
class SMUX;
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();
}
#define REMOVE_TIME (31)
using STG::TraffCounterImpl;
-using STG::TRF_IP_BEFORE;
-using STG::TRF_IP_AFTER;
namespace AsyncPoolST = STG::AsyncPoolST;
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()); });
});
}
//-----------------------------------------------------------------------------
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};
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,
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); });
}
//-----------------------------------------------------------------------------
#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>
#include <jthread.hpp>
#pragma GCC diagnostic pop
#include <cstdint>
+#include <ctime>
#define PROTOMAX (5)
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();
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;
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);
};
}
WriteServLog(Logger::get()),
lastScanMessages(0),
id(0),
- __connected(0),
- connected(__connected),
- __currIP(0),
- currIP(__currIP),
lastIPForDisconnect(0),
pingTime(0),
sysAdmin(a),
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()
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);
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),
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);
}
//-----------------------------------------------------------------------------
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);
if (ips.ConstData().find(ip))
{
- currIP = ip;
- lastIPForDisconnect = currIP;
+ m_currIP = ip;
+ lastIPForDisconnect = m_currIP;
}
else
{
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;
}
"%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());
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)
WriteServLog("Script OnDisconnect cannot be executed. File not found.");
}
- connected = false;
+ m_connected = false;
}
std::string reasonMessage(reason);
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");
}
else
{
- if (connected)
+ if (m_connected)
Disconnect(false, "not authorized");
}
{
STG_LOCKER lock(&mutex);
-if (!connected || tariff == NULL)
+if (!m_connected || tariff == NULL)
return;
double cost = 0;
{
STG_LOCKER lock(&mutex);
-if (!connected || tariff == NULL)
+if (!m_connected || tariff == NULL)
return;
double cost = 0;
}
}
//-----------------------------------------------------------------------------
-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);
{
STG_LOCKER lock(&mutex);
-if (connected)
+if (m_connected)
{
Disconnect(true, "fake");
Connect(true);
{
STG_LOCKER lock(&mutex);
// Reset traff
-if (connected)
+if (m_connected)
Disconnect(true, "fake");
WriteMonthStat();
properties.Stat().monthUp.reset();
properties.Stat().monthDown.reset();
-if (connected)
+if (m_connected)
Connect(true);
// Set new tariff
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)
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))
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-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);
}
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;
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;
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; }
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;
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;
#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
{
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;
}
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;
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);
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");
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)
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;
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);
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");
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()