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);
-
-pthread_mutexattr_t attr;
-pthread_mutexattr_init(&attr);
-pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
-pthread_mutex_init(&mutex, &attr);
+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); });
}
//-----------------------------------------------------------------------------
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),
sessionUpload(),
sessionDownload(),
sessionUploadModTime(stgTime),
- sessionDownloadModTime(stgTime),
- passiveNotifier(this),
- disabledNotifier(this),
- tariffNotifier(this),
- cashNotifier(this),
- ipNotifier(this)
+ sessionDownloadModTime(stgTime)
{
-if (&u == this)
- return;
-
-properties.tariffName.AddBeforeNotifier(&tariffNotifier);
-properties.passive.AddBeforeNotifier(&passiveNotifier);
-properties.disabled.AddAfterNotifier(&disabledNotifier);
-properties.cash.AddBeforeNotifier(&cashNotifier);
-ips.AddAfterNotifier(&ipNotifier);
+ if (&u == this)
+ return;
-properties.SetProperties(u.properties);
+ 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);
-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);
+ properties.SetProperties(u.properties);
}
//-----------------------------------------------------------------------------
void UserImpl::SetLogin(const std::string & l)
{
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
static int idGen = 0;
assert(login.empty() && "Login is already set");
login = l;
//-----------------------------------------------------------------------------
int UserImpl::ReadConf()
{
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
UserConf conf;
if (store->RestoreUserConf(&conf, login))
//-----------------------------------------------------------------------------
int UserImpl::ReadStat()
{
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
UserStat stat;
if (store->RestoreUserStat(&stat, login))
//-----------------------------------------------------------------------------
int UserImpl::WriteConf()
{
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
UserConf conf(properties.GetConf());
printfd(__FILE__, "UserImpl::WriteConf()\n");
//-----------------------------------------------------------------------------
int UserImpl::WriteStat()
{
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
UserStat stat(properties.GetStat());
if (store->SaveUserStat(stat, login))
//-----------------------------------------------------------------------------
int UserImpl::WriteMonthStat()
{
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
time_t tt = stgTime - 3600;
struct tm t1;
localtime_r(&tt, &t1);
//-----------------------------------------------------------------------------
int UserImpl::Authorize(uint32_t ip, uint32_t dirs, const Auth * auth)
{
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
/*
* Authorize user. It only means that user will be authorized. Nothing more.
* User can be connected or disconnected while authorized.
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
{
//-----------------------------------------------------------------------------
void UserImpl::Unauthorize(const Auth * auth, const std::string & reason)
{
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
/*
* Authorizer tries to unauthorize user, that was not authorized by it
*/
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;
}
//-----------------------------------------------------------------------------
bool UserImpl::IsAuthorizedBy(const Auth * auth) const
{
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
// Is this user authorized by specified authorizer?
return authorizedBy.find(auth) != authorizedBy.end();
}
//-----------------------------------------------------------------------------
std::vector<std::string> UserImpl::GetAuthorizers() const
{
- STG_LOCKER lock(&mutex);
+ std::lock_guard lock(m_mutex);
std::vector<std::string> list;
std::transform(authorizedBy.begin(), authorizedBy.end(), std::back_inserter(list), [](const auto auth){ return auth->GetVersion(); });
return list;
* Connect user to Internet. This function is differ from Authorize() !!!
*/
-STG_LOCKER lock(&mutex);
-
if (!fakeConnect)
{
std::string scriptOnConnect = settings->GetScriptsDir() + "/OnConnect";
"%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)
* Disconnect user from Internet. This function is differ from UnAuthorize() !!!
*/
-STG_LOCKER lock(&mutex);
-
if (!lastIPForDisconnect)
{
printfd(__FILE__, "lastIPForDisconnect\n");
WriteServLog("Script OnDisconnect cannot be executed. File not found.");
}
- connected = false;
+ m_connected = false;
}
std::string reasonMessage(reason);
//-----------------------------------------------------------------------------
void UserImpl::Run()
{
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
if (stgTime > lastWriteStat + settings->GetStatWritePeriod())
{
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");
}
//-----------------------------------------------------------------------------
void UserImpl::UpdatePingTime(time_t t)
{
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
if (t)
pingTime = t;
else
void UserImpl::AddTraffStatU(int dir, uint32_t ip, uint32_t len)
#endif
{
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
-if (!connected || tariff == NULL)
+if (!m_connected || tariff == NULL)
return;
double cost = 0;
void UserImpl::AddTraffStatD(int dir, uint32_t ip, uint32_t len)
#endif
{
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_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);
+std::lock_guard lock(m_mutex);
std::string scriptOnAdd = settings->GetScriptsDir() + "/OnUserAdd";
//-----------------------------------------------------------------------------
void UserImpl::OnDelete()
{
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
std::string scriptOnDel = settings->GetScriptsDir() + "/OnUserDel";
TraffStat ts;
{
- STG_LOCKER lock(&mutex);
+ std::lock_guard lock(m_mutex);
ts.swap(traffStat);
}
if (!hard)
{
printfd(__FILE__, "UserImpl::WriteDetailStat() - pushing detail stat to queue\n");
- STG_LOCKER lock(&mutex);
+ std::lock_guard lock(m_mutex);
traffStatSaved.second.swap(ts);
traffStatSaved.first = lastWriteDetailedStat;
}
//-----------------------------------------------------------------------------
double UserImpl::GetPassiveTimePart() const
{
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
+return getPassiveTimePart();
+}
+double UserImpl::getPassiveTimePart() const
+{
static const std::array<unsigned, 12> daysInMonth{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
struct tm tms;
//-----------------------------------------------------------------------------
void UserImpl::SetPassiveTimeAsNewUser()
{
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
time_t t = stgTime;
struct tm tm;
//-----------------------------------------------------------------------------
void UserImpl::MidnightResetSessionStat()
{
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
-if (connected)
+if (m_connected)
{
Disconnect(true, "fake");
Connect(true);
//-----------------------------------------------------------------------------
void UserImpl::ProcessNewMonth()
{
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_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
//-----------------------------------------------------------------------------
void UserImpl::ProcessDayFeeSpread()
{
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
if (passive.ConstData() || tariff == NULL)
return;
//-----------------------------------------------------------------------------
void UserImpl::ProcessDayFee()
{
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
if (tariff == NULL)
return;
double passiveTimePart = 1.0;
if (!settings->GetFullFee())
{
- passiveTimePart = GetPassiveTimePart();
+ passiveTimePart = getPassiveTimePart();
}
else
{
//-----------------------------------------------------------------------------
void UserImpl::ProcessDailyFee()
{
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
if (passive.ConstData() || tariff == NULL)
return;
time_t t = stgTime;
localtime_r(&t, &tms);
+std::lock_guard lock(m_mutex);
+
double passiveTimePart = 1.0;
if (!settings->GetFullFee())
{
- passiveTimePart = GetPassiveTimePart();
+ passiveTimePart = getPassiveTimePart();
}
else
{
//-----------------------------------------------------------------------------
int UserImpl::AddMessage(Message * msg)
{
-STG_LOCKER lock(&mutex);
+std::lock_guard lock(m_mutex);
if (SendMessage(*msg))
{
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,
+ std::lock_guard lock(m_mutex);
+ 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);
+ std::lock_guard lock(m_mutex);
+ 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())
+ std::lock_guard lock(m_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);
+ std::lock_guard lock(m_mutex);
+ 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);
}