X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/a500fb72810060e52d87ad2c2e4691531f0bcc5a..HEAD:/projects/stargazer/user_impl.cpp diff --git a/projects/stargazer/user_impl.cpp b/projects/stargazer/user_impl.cpp index f5f4c4b4..af94d477 100644 --- a/projects/stargazer/user_impl.cpp +++ b/projects/stargazer/user_impl.cpp @@ -88,10 +88,6 @@ UserImpl::UserImpl(const Settings * s, WriteServLog(Logger::get()), lastScanMessages(0), id(0), - __connected(0), - connected(__connected), - __currIP(0), - currIP(__currIP), lastIPForDisconnect(0), pingTime(0), sysAdmin(a), @@ -139,14 +135,9 @@ UserImpl::UserImpl(const Settings * s, userdata8(properties.userdata8), userdata9(properties.userdata9), sessionUploadModTime(stgTime), - sessionDownloadModTime(stgTime), - passiveNotifier(this), - disabledNotifier(this), - tariffNotifier(this), - cashNotifier(this), - ipNotifier(this) + sessionDownloadModTime(stgTime) { -Init(); + Init(); } //----------------------------------------------------------------------------- void UserImpl::Init() @@ -158,16 +149,11 @@ ips = UserIPs::parse("*"); lastWriteStat = stgTime + random() % settings->GetStatWritePeriod(); lastWriteDetailedStat = stgTime; -properties.tariffName.AddBeforeNotifier(&tariffNotifier); -properties.passive.AddBeforeNotifier(&passiveNotifier); -properties.disabled.AddAfterNotifier(&disabledNotifier); -properties.cash.AddBeforeNotifier(&cashNotifier); -ips.AddAfterNotifier(&ipNotifier); - -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) @@ -177,10 +163,6 @@ UserImpl::UserImpl(const UserImpl & u) lastScanMessages(0), login(u.login), id(u.id), - __connected(0), - connected(__connected), - __currIP(u.__currIP), - currIP(__currIP), lastIPForDisconnect(0), pingTime(u.pingTime), sysAdmin(u.sysAdmin), @@ -233,42 +215,23 @@ UserImpl::UserImpl(const UserImpl & u) sessionUpload(), sessionDownload(), sessionUploadModTime(stgTime), - sessionDownloadModTime(stgTime), - passiveNotifier(this), - disabledNotifier(this), - tariffNotifier(this), - cashNotifier(this), - ipNotifier(this) + sessionDownloadModTime(stgTime) { -if (&u == this) - return; - -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; @@ -277,7 +240,7 @@ id = idGen++; //----------------------------------------------------------------------------- int UserImpl::ReadConf() { -STG_LOCKER lock(&mutex); +std::lock_guard lock(m_mutex); UserConf conf; if (store->RestoreUserConf(&conf, login)) @@ -325,7 +288,7 @@ return 0; //----------------------------------------------------------------------------- int UserImpl::ReadStat() { -STG_LOCKER lock(&mutex); +std::lock_guard lock(m_mutex); UserStat stat; if (store->RestoreUserStat(&stat, login)) @@ -344,7 +307,7 @@ return 0; //----------------------------------------------------------------------------- int UserImpl::WriteConf() { -STG_LOCKER lock(&mutex); +std::lock_guard lock(m_mutex); UserConf conf(properties.GetConf()); printfd(__FILE__, "UserImpl::WriteConf()\n"); @@ -363,7 +326,7 @@ return 0; //----------------------------------------------------------------------------- int UserImpl::WriteStat() { -STG_LOCKER lock(&mutex); +std::lock_guard lock(m_mutex); UserStat stat(properties.GetStat()); if (store->SaveUserStat(stat, login)) @@ -382,7 +345,7 @@ return 0; //----------------------------------------------------------------------------- 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); @@ -402,7 +365,7 @@ return 0; //----------------------------------------------------------------------------- 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. @@ -428,7 +391,7 @@ dirsFromBits(enabledDirs, dirs); if (!authorizedBy.empty()) { - if (currIP != ip) + if (m_currIP != ip) { // We are already authorized, but with different IP address errorStr = "User " + login + " already authorized with IP address " + inet_ntostring(ip); @@ -458,8 +421,8 @@ else if (ips.ConstData().find(ip)) { - currIP = ip; - lastIPForDisconnect = currIP; + m_currIP = ip; + lastIPForDisconnect = m_currIP; } else { @@ -480,7 +443,7 @@ return 0; //----------------------------------------------------------------------------- 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 */ @@ -492,9 +455,9 @@ authorizedModificationTime = stgTime; if (authorizedBy.empty()) { lastDisconnectReason = reason; - lastIPForDisconnect = currIP; - currIP = 0; // DelUser in traffcounter - if (connected) + lastIPForDisconnect = m_currIP; + m_currIP = 0; // DelUser in traffcounter + if (m_connected) Disconnect(false, "not authorized"); return; } @@ -502,14 +465,14 @@ if (authorizedBy.empty()) //----------------------------------------------------------------------------- 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 UserImpl::GetAuthorizers() const { - STG_LOCKER lock(&mutex); + std::lock_guard lock(m_mutex); std::vector list; std::transform(authorizedBy.begin(), authorizedBy.end(), std::back_inserter(list), [](const auto auth){ return auth->GetVersion(); }); return list; @@ -521,8 +484,6 @@ void UserImpl::Connect(bool fakeConnect) * Connect user to Internet. This function is differ from Authorize() !!! */ -STG_LOCKER lock(&mutex); - if (!fakeConnect) { std::string scriptOnConnect = settings->GetScriptsDir() + "/OnConnect"; @@ -536,7 +497,7 @@ if (!fakeConnect) "%s \"%s\" \"%s\" \"%f\" \"%d\" \"%s\"", scriptOnConnect.c_str(), login.c_str(), - inet_ntostring(currIP).c_str(), + inet_ntostring(m_currIP).c_str(), cash.ConstData(), id, dirs.c_str()); @@ -555,17 +516,17 @@ if (!fakeConnect) WriteServLog("Script %s cannot be executed. File not found.", scriptOnConnect.c_str()); } - connected = true; + m_connected = true; } -if (!settings->GetDisableSessionLog() && store->WriteUserConnect(login, currIP)) +if (!settings->GetDisableSessionLog() && store->WriteUserConnect(login, m_currIP)) { WriteServLog("Cannot write connect for user %s.", login.c_str()); WriteServLog("%s", store->GetStrError().c_str()); } if (!fakeConnect) - lastIPForDisconnect = currIP; + lastIPForDisconnect = m_currIP; } //----------------------------------------------------------------------------- void UserImpl::Disconnect(bool fakeDisconnect, const std::string & reason) @@ -574,8 +535,6 @@ 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"); @@ -615,7 +574,7 @@ if (!fakeDisconnect) WriteServLog("Script OnDisconnect cannot be executed. File not found."); } - connected = false; + m_connected = false; } std::string reasonMessage(reason); @@ -640,7 +599,7 @@ sessionDownloadModTime = stgTime; //----------------------------------------------------------------------------- void UserImpl::Run() { -STG_LOCKER lock(&mutex); +std::lock_guard lock(m_mutex); if (stgTime > lastWriteStat + settings->GetStatWritePeriod()) { @@ -665,13 +624,13 @@ if (passive.ConstData() if (!authorizedBy.empty()) { - if (connected) + if (m_connected) properties.Stat().lastActivityTime = stgTime; - if (!connected && IsInetable()) + if (!m_connected && IsInetable()) Connect(); - if (connected && !IsInetable()) + if (m_connected && !IsInetable()) { if (disabled) Disconnect(false, "disabled"); @@ -689,7 +648,7 @@ if (!authorizedBy.empty()) } else { - if (connected) + if (m_connected) Disconnect(false, "not authorized"); } @@ -697,7 +656,7 @@ else //----------------------------------------------------------------------------- void UserImpl::UpdatePingTime(time_t t) { -STG_LOCKER lock(&mutex); +std::lock_guard lock(m_mutex); if (t) pingTime = t; else @@ -732,9 +691,9 @@ void UserImpl::AddTraffStatU(int dir, uint32_t ip, uint16_t port, uint32_t len) 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; @@ -825,9 +784,9 @@ void UserImpl::AddTraffStatD(int dir, uint32_t ip, uint16_t port, uint32_t len) 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; @@ -911,57 +870,9 @@ else } } //----------------------------------------------------------------------------- -void UserImpl::AddCurrIPBeforeNotifier(CURR_IP_NOTIFIER * notifier) -{ -STG_LOCKER lock(&mutex); -currIP.AddBeforeNotifier(notifier); -} -//----------------------------------------------------------------------------- -void UserImpl::DelCurrIPBeforeNotifier(const CURR_IP_NOTIFIER * notifier) -{ -STG_LOCKER lock(&mutex); -currIP.DelBeforeNotifier(notifier); -} -//----------------------------------------------------------------------------- -void UserImpl::AddCurrIPAfterNotifier(CURR_IP_NOTIFIER * notifier) -{ -STG_LOCKER lock(&mutex); -currIP.AddAfterNotifier(notifier); -} -//----------------------------------------------------------------------------- -void UserImpl::DelCurrIPAfterNotifier(const CURR_IP_NOTIFIER * notifier) -{ -STG_LOCKER lock(&mutex); -currIP.DelAfterNotifier(notifier); -} -//----------------------------------------------------------------------------- -void UserImpl::AddConnectedBeforeNotifier(CONNECTED_NOTIFIER * notifier) -{ -STG_LOCKER lock(&mutex); -connected.AddBeforeNotifier(notifier); -} -//----------------------------------------------------------------------------- -void UserImpl::DelConnectedBeforeNotifier(const CONNECTED_NOTIFIER * notifier) -{ -STG_LOCKER lock(&mutex); -connected.DelBeforeNotifier(notifier); -} -//----------------------------------------------------------------------------- -void UserImpl::AddConnectedAfterNotifier(CONNECTED_NOTIFIER * notifier) -{ -STG_LOCKER lock(&mutex); -connected.AddAfterNotifier(notifier); -} -//----------------------------------------------------------------------------- -void UserImpl::DelConnectedAfterNotifier(const CONNECTED_NOTIFIER * notifier) -{ -STG_LOCKER lock(&mutex); -connected.DelAfterNotifier(notifier); -} -//----------------------------------------------------------------------------- void UserImpl::OnAdd() { -STG_LOCKER lock(&mutex); +std::lock_guard lock(m_mutex); std::string scriptOnAdd = settings->GetScriptsDir() + "/OnUserAdd"; @@ -979,7 +890,7 @@ else //----------------------------------------------------------------------------- void UserImpl::OnDelete() { -STG_LOCKER lock(&mutex); +std::lock_guard lock(m_mutex); std::string scriptOnDel = settings->GetScriptsDir() + "/OnUserDel"; @@ -1016,7 +927,7 @@ if (!traffStatSaved.second.empty()) TraffStat ts; { - STG_LOCKER lock(&mutex); + std::lock_guard lock(m_mutex); ts.swap(traffStat); } @@ -1032,7 +943,7 @@ if (ts.size() && !disabledDetailStat) 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; } @@ -1045,8 +956,12 @@ return 0; //----------------------------------------------------------------------------- double UserImpl::GetPassiveTimePart() const { -STG_LOCKER lock(&mutex); +std::lock_guard lock(m_mutex); +return getPassiveTimePart(); +} +double UserImpl::getPassiveTimePart() const +{ static const std::array daysInMonth{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; struct tm tms; @@ -1071,7 +986,7 @@ return static_cast(dt) / secMonth; //----------------------------------------------------------------------------- void UserImpl::SetPassiveTimeAsNewUser() { -STG_LOCKER lock(&mutex); +std::lock_guard lock(m_mutex); time_t t = stgTime; struct tm tm; @@ -1085,9 +1000,9 @@ passiveTime = static_cast(pt * 24 * 3600 * daysCurrMon); //----------------------------------------------------------------------------- void UserImpl::MidnightResetSessionStat() { -STG_LOCKER lock(&mutex); +std::lock_guard lock(m_mutex); -if (connected) +if (m_connected) { Disconnect(true, "fake"); Connect(true); @@ -1096,9 +1011,9 @@ if (connected) //----------------------------------------------------------------------------- void UserImpl::ProcessNewMonth() { -STG_LOCKER lock(&mutex); +std::lock_guard lock(m_mutex); // Reset traff -if (connected) +if (m_connected) Disconnect(true, "fake"); WriteMonthStat(); @@ -1106,7 +1021,7 @@ WriteMonthStat(); properties.Stat().monthUp.reset(); properties.Stat().monthDown.reset(); -if (connected) +if (m_connected) Connect(true); // Set new tariff @@ -1139,7 +1054,7 @@ if (nextTariff.ConstData() != "") //----------------------------------------------------------------------------- void UserImpl::ProcessDayFeeSpread() { -STG_LOCKER lock(&mutex); +std::lock_guard lock(m_mutex); if (passive.ConstData() || tariff == NULL) return; @@ -1176,7 +1091,7 @@ ResetPassiveTime(); //----------------------------------------------------------------------------- void UserImpl::ProcessDayFee() { -STG_LOCKER lock(&mutex); +std::lock_guard lock(m_mutex); if (tariff == NULL) return; @@ -1187,7 +1102,7 @@ if (tariff->GetPeriod() != Tariff::MONTH) double passiveTimePart = 1.0; if (!settings->GetFullFee()) { - passiveTimePart = GetPassiveTimePart(); + passiveTimePart = getPassiveTimePart(); } else { @@ -1247,7 +1162,7 @@ switch (settings->GetFeeChargeType()) //----------------------------------------------------------------------------- void UserImpl::ProcessDailyFee() { -STG_LOCKER lock(&mutex); +std::lock_guard lock(m_mutex); if (passive.ConstData() || tariff == NULL) return; @@ -1284,10 +1199,12 @@ struct tm tms; 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 { @@ -1355,7 +1272,7 @@ if (tariff != NULL) //----------------------------------------------------------------------------- int UserImpl::AddMessage(Message * msg) { -STG_LOCKER lock(&mutex); +std::lock_guard lock(m_mutex); if (SendMessage(*msg)) { @@ -1399,7 +1316,7 @@ int ret = -1; std::set::iterator it(authorizedBy.begin()); while (it != authorizedBy.end()) { - if (!(*it++)->SendMessage(msg, currIP)) + if (!(*it++)->SendMessage(msg, m_currIP)) ret = 0; } if (!ret) @@ -1479,7 +1396,7 @@ std::string UserImpl::GetParamValue(const std::string & name) const return stream.str(); } if (lowerName == "login") return login; - if (lowerName == "currip") return currIP.ToString(); + if (lowerName == "currip") return m_currIP.ToString(); if (lowerName == "enableddirs") return GetEnabledDirs(); if (lowerName == "tariff") return properties.tariffName; if (properties.Exists(lowerName)) @@ -1493,51 +1410,55 @@ std::string UserImpl::GetParamValue(const std::string & name) const //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -void STG::CHG_PASSIVE_NOTIFIER::Notify(const int & oldPassive, const int & newPassive) +void UserImpl::onPassiveChange(int oldVal, int newVal) { -if (newPassive && !oldPassive && user->tariff != NULL) - user->properties.cash.Set(user->cash - user->tariff->GetPassiveCost(), - *user->sysAdmin, - user->login, - *user->store, + 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(&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); }