2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
27 $Date: 2010/11/03 10:50:03 $
36 #include <unistd.h> // access
43 #include "script_executer.h"
48 USER::USER(const SETTINGS * s,
49 const BASE_STORE * st,
52 const map<uint32_t, user_iter> * ipIdx)
54 WriteServLog(GetStgLogger()),
58 connected(__connected),
62 lastIPForDisconnect(0),
67 tariff(tariffs->GetNoTariff()),
71 lastCashAdd(property.lastCashAdd),
72 passiveTime(property.passiveTime),
73 lastCashAddTime(property.lastCashAddTime),
74 freeMb(property.freeMb),
75 lastActivityTime(property.lastActivityTime),
76 password(property.password),
77 passive(property.passive),
78 disabled(property.disabled),
79 disabledDetailStat(property.disabledDetailStat),
80 alwaysOnline(property.alwaysOnline),
81 tariffName(property.tariffName),
82 nextTariff(property.nextTariff),
83 address(property.address),
85 group(property.group),
86 email(property.email),
87 phone(property.phone),
88 realName(property.realName),
89 credit(property.credit),
90 creditExpire(property.creditExpire),
92 userdata0(property.userdata0),
93 userdata1(property.userdata1),
94 userdata2(property.userdata2),
95 userdata3(property.userdata3),
96 userdata4(property.userdata4),
97 userdata5(property.userdata5),
98 userdata6(property.userdata6),
99 userdata7(property.userdata7),
100 userdata8(property.userdata8),
101 userdata9(property.userdata9),
102 passiveNotifier(this),
103 tariffNotifier(this),
110 password = "*_EMPTY_PASSWORD_*";
111 tariffName = NO_TARIFF_NAME;
113 /*traffStatInUse = 0;
114 traffStat = &traffStatInternal[0];*/
115 tariff = tariffs->GetNoTariff();
118 lastWriteStat = stgTime + random() % settings->GetStatWritePeriod();
119 lastWriteDeatiledStat = stgTime;
120 lastSwapDeatiledStat = stgTime;
122 property.tariffName.AddBeforeNotifier(&tariffNotifier);
123 property.passive.AddBeforeNotifier(&passiveNotifier);
124 property.cash.AddBeforeNotifier(&cashNotifier);
125 currIP.AddAfterNotifier(&ipNotifier);
127 lastScanMessages = 0;
129 writeFreeMbTraffCost = settings->GetWriteFreeMbTraffCost();
131 pthread_mutexattr_t attr;
132 pthread_mutexattr_init(&attr);
133 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
134 pthread_mutex_init(&mutex, &attr);
136 //-----------------------------------------------------------------------------
137 USER::USER(const USER & u)
138 : property(u.settings),
139 WriteServLog(GetStgLogger()),
142 __connected(u.__connected),
143 connected(__connected),
144 __currIP(u.__currIP),
146 lastIPForDisconnect(0),
147 pingTime(u.pingTime),
148 sysAdmin(u.sysAdmin),
155 lastCashAdd(property.lastCashAdd),
156 passiveTime(property.passiveTime),
157 lastCashAddTime(property.lastCashAddTime),
158 freeMb(property.freeMb),
159 lastActivityTime(property.lastActivityTime),
160 password(property.password),
161 passive(property.passive),
162 disabled(property.disabled),
163 disabledDetailStat(property.disabledDetailStat),
164 alwaysOnline(property.alwaysOnline),
165 tariffName(property.tariffName),
166 nextTariff(property.nextTariff),
167 address(property.address),
169 group(property.group),
170 email(property.email),
171 phone(property.phone),
172 realName(property.realName),
173 credit(property.credit),
174 creditExpire(property.creditExpire),
176 userdata0(property.userdata0),
177 userdata1(property.userdata1),
178 userdata2(property.userdata2),
179 userdata3(property.userdata3),
180 userdata4(property.userdata4),
181 userdata5(property.userdata5),
182 userdata6(property.userdata6),
183 userdata7(property.userdata7),
184 userdata8(property.userdata8),
185 userdata9(property.userdata9),
186 passiveNotifier(this),
187 tariffNotifier(this),
195 //traffStatInUse = 0;
200 /*traffStat = &traffStatInternal[traffStatInUse % 2];
201 traffStatToWrite = &traffStatInternal[(traffStatInUse +1) % 2];*/
203 lastWriteStat = u.lastWriteStat;
204 lastWriteDeatiledStat = u.lastWriteDeatiledStat;
205 lastSwapDeatiledStat = u.lastSwapDeatiledStat;
207 settings = u.settings;
209 property.tariffName.AddBeforeNotifier(&tariffNotifier);
210 property.passive.AddBeforeNotifier(&passiveNotifier);
211 property.cash.AddBeforeNotifier(&cashNotifier);
212 currIP.AddAfterNotifier(&ipNotifier);
214 lastScanMessages = 0;
216 writeFreeMbTraffCost = settings->GetWriteFreeMbTraffCost();
218 pthread_mutexattr_t attr;
219 pthread_mutexattr_init(&attr);
220 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
221 pthread_mutex_init(&mutex, &attr);
223 //-----------------------------------------------------------------------------
226 property.passive.DelBeforeNotifier(&passiveNotifier);
227 property.tariffName.DelBeforeNotifier(&tariffNotifier);
228 pthread_mutex_destroy(&mutex);
230 //-----------------------------------------------------------------------------
231 void USER::SetLogin(string const & l)
233 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
234 assert(login.empty() && "Login is already set");
236 id = userIDGenerator.GetNextID();
238 //-----------------------------------------------------------------------------
241 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
244 if (store->RestoreUserConf(&uc, login))
246 WriteServLog("Cannot read conf for user %s.", login.c_str());
247 WriteServLog("%s", store->GetStrError().c_str());
248 printfd(__FILE__, "Cannot read conf for user %s.\n", login.c_str());
249 printfd(__FILE__, "%s\n", store->GetStrError().c_str());
253 password = uc.password;
254 passive = uc.passive;
255 disabled = uc.disabled;
256 disabledDetailStat = uc.disabledDetailStat;
257 alwaysOnline = uc.alwaysOnline;
258 tariffName = uc.tariffName;
259 address = uc.address;
263 realName = uc.realName;
266 nextTariff = uc.nextTariff;
267 userdata0 = uc.userdata[0];
268 userdata1 = uc.userdata[1];
269 userdata2 = uc.userdata[2];
270 userdata3 = uc.userdata[3];
271 userdata4 = uc.userdata[4];
272 userdata5 = uc.userdata[5];
273 userdata6 = uc.userdata[6];
274 userdata7 = uc.userdata[7];
275 userdata8 = uc.userdata[8];
276 userdata9 = uc.userdata[9];
278 creditExpire = uc.creditExpire;
281 tariff = tariffs->FindByName(tariffName);
284 WriteServLog("Cannot read user %s. Tariff %s not exist.",
285 login.c_str(), property.tariffName.Get().c_str());
291 //-----------------------------------------------------------------------------
294 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
297 if (store->RestoreUserStat(&us, login))
299 WriteServLog("Cannot read stat for user %s.", login.c_str());
300 WriteServLog("%s", store->GetStrError().c_str());
301 printfd(__FILE__, "Cannot read stat for user %s.\n", login.c_str());
302 printfd(__FILE__, "%s\n", store->GetStrError().c_str());
310 lastCashAdd = us.lastCashAdd;
311 lastCashAddTime = us.lastCashAddTime;
312 passiveTime = us.passiveTime;
313 lastActivityTime = us.lastActivityTime;
317 //-----------------------------------------------------------------------------
318 int USER::WriteConf()
320 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
323 uc.password = password;
324 uc.passive = passive;
325 uc.disabled = disabled;
326 uc.disabledDetailStat = disabledDetailStat;
327 uc.alwaysOnline = alwaysOnline;
328 uc.tariffName = tariffName;
329 uc.address = address;
333 uc.realName = realName;
336 uc.nextTariff = nextTariff;
337 uc.userdata[0] = userdata0;
338 uc.userdata[1] = userdata1;
339 uc.userdata[2] = userdata2;
340 uc.userdata[3] = userdata3;
341 uc.userdata[4] = userdata4;
342 uc.userdata[5] = userdata5;
343 uc.userdata[6] = userdata6;
344 uc.userdata[7] = userdata7;
345 uc.userdata[8] = userdata8;
346 uc.userdata[9] = userdata9;
348 uc.creditExpire = creditExpire;
351 printfd(__FILE__, "USER::WriteConf()\n");
353 if (store->SaveUserConf(uc, login))
355 WriteServLog("Cannot write conf for user %s.", login.c_str());
356 WriteServLog("%s", store->GetStrError().c_str());
357 printfd(__FILE__, "Cannot write conf for user %s.\n", login.c_str());
358 printfd(__FILE__, "%s\n", store->GetStrError().c_str());
364 //-----------------------------------------------------------------------------
365 int USER::WriteStat()
367 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
374 us.lastCashAdd = lastCashAdd;
375 us.lastCashAddTime = lastCashAddTime;
376 us.passiveTime = passiveTime;
377 us.lastActivityTime = lastActivityTime;
379 printfd(__FILE__, "USER::WriteStat()\n");
381 if (store->SaveUserStat(us, login))
383 WriteServLog("Cannot write stat for user %s.", login.c_str());
384 WriteServLog("%s", store->GetStrError().c_str());
385 printfd(__FILE__, "Cannot write stat for user %s.\n", login.c_str());
386 printfd(__FILE__, "%s\n", store->GetStrError().c_str());
390 lastWriteStat = stgTime;
394 //-----------------------------------------------------------------------------
395 int USER::WriteMonthStat()
397 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
400 time_t tt = stgTime - 3600;
407 us.lastCashAdd = lastCashAdd;
408 us.lastCashAddTime = lastCashAddTime;
409 us.passiveTime = passiveTime;
410 us.lastActivityTime = lastActivityTime;
412 if (store->SaveMonthStat(us, t1->tm_mon, t1->tm_year, login))
414 WriteServLog("Cannot write month stat for user %s.", login.c_str());
415 WriteServLog("%s", store->GetStrError().c_str());
416 printfd(__FILE__, "Cannot write month stat for user %s.\n", login.c_str());
417 printfd(__FILE__, "%s\n", store->GetStrError().c_str());
423 //-----------------------------------------------------------------------------
424 int USER::Authorize(uint32_t ip, const string &, uint32_t dirs, const BASE_AUTH * auth)
426 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
428 * Authorize user. It only means that user will be authorized. Nothing more.
429 * User can be connected or disconnected while authorized.
430 * Example: user is authorized but disconnected due to 0 money or blocking
434 * Prevent double authorization by identical authorizers
436 if (authorizedBy.find(auth) != authorizedBy.end())
442 for (int i = 0; i < DIR_NUM; i++)
444 enabledDirs[i] = dirs & (1 << i);
447 if (authorizedBy.size())
451 // We are already authorized, but with different IP address
452 errorStr = "User " + login + " alredy authorized with IP address " + inet_ntostring(ip);
456 map<uint32_t, user_iter>::const_iterator ci = ipIndex->find(ip);
457 if (ci != ipIndex->end())
459 // Address is already present in IP-index
460 // If it's not our IP - throw an error
461 if (&(*ci->second) != this)
463 errorStr = "IP address " + inet_ntostring(ip) + " alredy in use";
470 if (ipIndex->find(ip) != ipIndex->end())
472 // Address is already present in IP-index
473 errorStr = "IP address " + inet_ntostring(ip) + " alredy in use";
477 if (ips.ConstData().IsIPInIPS(ip))
480 lastIPForDisconnect = currIP;
484 printfd(__FILE__, " user %s: ips = %s\n", login.c_str(), ips.ConstData().GetIpStr().c_str());
485 errorStr = "IP address " + inet_ntostring(ip) + " not belong user " + login;
490 authorizedBy.insert(auth);
496 //-----------------------------------------------------------------------------
497 void USER::Unauthorize(const BASE_AUTH * auth)
499 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
501 * Authorizer tries to unauthorize user, that was not authorized by it
503 if (!authorizedBy.erase(auth))
506 if (authorizedBy.empty())
508 lastIPForDisconnect = currIP;
509 currIP = 0; // DelUser in traffcounter
513 //-----------------------------------------------------------------------------
514 bool USER::IsAuthorizedBy(const BASE_AUTH * auth) const
516 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
517 // Is this user authorized by specified authorizer?
518 return authorizedBy.find(auth) != authorizedBy.end();
520 //-----------------------------------------------------------------------------
521 void USER::Connect(bool fakeConnect)
524 * Connect user to Internet. This function is differ from Authorize() !!!
527 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
531 string scriptOnConnect = settings->GetScriptDir() + "/OnConnect";
533 if (access(scriptOnConnect.c_str(), X_OK) == 0)
535 char dirsStr[DIR_NUM + 1];
536 dirsStr[DIR_NUM] = 0;
537 for (int i = 0; i < DIR_NUM; i++)
539 dirsStr[i] = enabledDirs[i] ? '1' : '0';
542 string scriptOnConnectParams;
543 strprintf(&scriptOnConnectParams,
544 "%s \"%s\" \"%s\" \"%f\" \"%d\" \"%s\"",
545 scriptOnConnect.c_str(),
547 inet_ntostring(currIP).c_str(),
552 ScriptExec(scriptOnConnectParams);
556 WriteServLog("Script %s cannot be executed. File not found.", scriptOnConnect.c_str());
562 if (store->WriteUserConnect(login, currIP))
564 WriteServLog("Cannot write connect for user %s.", login.c_str());
565 WriteServLog("%s", store->GetStrError().c_str());
569 lastIPForDisconnect = currIP;
571 //printfd(__FILE__, "Connect. user name \'%s\' ip=%s\n", login.c_str(), inet_ntostring(currIP).c_str());
572 /*if (settings->GetLogUserConnectDisconnect())
573 WriteServLog("User \'%s\', %s: Connect.", login.c_str(), inet_ntostring(currIP).c_str());*/
575 //-----------------------------------------------------------------------------
576 void USER::Disconnect(bool fakeDisconnect, const std::string & reason)
579 * Disconnect user from Internet. This function is differ from UnAuthorize() !!!
582 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
584 if (!lastIPForDisconnect)
586 printfd(__FILE__, "lastIPForDisconnect\n");
592 string scriptOnDisonnect = settings->GetScriptDir() + "/OnDisconnect";
594 if (access(scriptOnDisonnect.c_str(), X_OK) == 0)
596 char dirsStr[DIR_NUM + 1];
597 dirsStr[DIR_NUM] = 0;
598 for (int i = 0; i < DIR_NUM; i++)
600 dirsStr[i] = enabledDirs[i] ? '1' : '0';
603 string scriptOnDisonnectParams;
604 strprintf(&scriptOnDisonnectParams,
605 "%s \"%s\" \"%s\" \"%f\" \"%d\" \"%s\"",
606 scriptOnDisonnect.c_str(),
608 inet_ntostring(lastIPForDisconnect).c_str(),
613 ScriptExec(scriptOnDisonnectParams);
617 WriteServLog("Script OnDisconnect cannot be executed. File not found.");
623 if (store->WriteUserDisconnect(login, up, down, sessionUpload, sessionDownload, cash, freeMb, reason))
625 WriteServLog("Cannot write disconnect for user %s.", login.c_str());
626 WriteServLog("%s", store->GetStrError().c_str());
629 //printfd(__FILE__, "Disconnect. User name \'%s\' ip=%s reason: '%s'\n", login.c_str(), inet_ntostring(lastIPForDisconnect).c_str(), reason.c_str());
630 /*if (settings->GetLogUserConnectDisconnect())
631 WriteServLog("User \'%s\', %s: Disconnect.", login.c_str(), inet_ntostring(lastIPForDisconnect).c_str());*/
634 lastIPForDisconnect = 0;
636 DIR_TRAFF zeroSesssion;
638 sessionUpload = zeroSesssion;
639 sessionDownload = zeroSesssion;
641 //-----------------------------------------------------------------------------
642 void USER::PrintUser() const
645 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
646 cout << "============================================================" << endl;
647 cout << "id=" << id << endl;
648 cout << "login=" << login << endl;
649 cout << "password=" << password << endl;
650 cout << "passive=" << passive << endl;
651 cout << "disabled=" << disabled << endl;
652 cout << "disabledDetailStat=" << disabledDetailStat << endl;
653 cout << "alwaysOnline=" << alwaysOnline << endl;
654 cout << "tariffName=" << tariffName << endl;
655 cout << "address=" << address << endl;
656 cout << "phone=" << phone << endl;
657 cout << "email=" << email << endl;
658 cout << "note=" << note << endl;
659 cout << "realName=" <<realName << endl;
660 cout << "group=" << group << endl;
661 cout << "credit=" << credit << endl;
662 cout << "nextTariff=" << nextTariff << endl;
663 cout << "userdata0" << userdata0 << endl;
664 cout << "userdata1" << userdata1 << endl;
665 cout << "creditExpire=" << creditExpire << endl;
666 cout << "ips=" << ips << endl;
667 cout << "------------------------" << endl;
668 cout << "up=" << up << endl;
669 cout << "down=" << down << endl;
670 cout << "cash=" << cash << endl;
671 cout << "freeMb=" << freeMb << endl;
672 cout << "lastCashAdd=" << lastCashAdd << endl;
673 cout << "lastCashAddTime=" << lastCashAddTime << endl;
674 cout << "passiveTime=" << passiveTime << endl;
675 cout << "lastActivityTime=" << lastActivityTime << endl;
676 cout << "============================================================" << endl;
678 //-----------------------------------------------------------------------------
681 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
683 if (stgTime - lastWriteStat > settings->GetStatWritePeriod())
685 printfd(__FILE__, "USER::WriteStat user=%s\n", GetLogin().c_str());
688 if (creditExpire.ConstData() && creditExpire.ConstData() < stgTime)
690 WriteServLog("User: %s. Credit expired.", login.c_str());
696 if (passive.ConstData()
697 && (stgTime % 30 == 0)
698 && (passiveTime.ModificationTime() != stgTime))
700 passiveTime = passiveTime + (stgTime - passiveTime.ModificationTime());
701 printfd(__FILE__, "===== %s: passiveTime=%d =====\n", login.c_str(), passiveTime.ConstData());
704 if (!authorizedBy.empty())
708 lastActivityTime = *const_cast<time_t *>(&stgTime);
710 if (!connected && IsInetable())
714 if (connected && !IsInetable())
717 Disconnect(false, "disabled");
719 Disconnect(false, "passive");
721 Disconnect(false, "no cash");
724 if (stgTime - lastScanMessages > 10)
727 lastScanMessages = stgTime;
734 Disconnect(false, "not authorized");
739 //-----------------------------------------------------------------------------
740 void USER::UpdatePingTime(time_t t)
742 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
743 //printfd(__FILE__, "UpdatePingTime(%d) %s\n", t, login.c_str());
749 //-----------------------------------------------------------------------------
750 bool USER::IsInetable()
752 //STG_LOCKER lock(&mutex, __FILE__, __LINE__);
754 if (disabled || passive)
757 if (settings->GetFreeMbAllowInet())
763 if (settings->GetShowFeeInCash())
765 return (cash >= -credit);
768 return (cash - tariff->GetFee() >= -credit);
770 //-----------------------------------------------------------------------------
771 string USER::GetEnabledDirs()
773 //STG_LOCKER lock(&mutex, __FILE__, __LINE__);
776 for(int i = 0; i < DIR_NUM; i++)
777 dirs += enabledDirs[i] ? "1" : "0";
780 //-----------------------------------------------------------------------------
781 #ifdef TRAFF_STAT_WITH_PORTS
782 void USER::AddTraffStatU(int dir, uint32_t ip, uint16_t port, uint32_t len)
784 void USER::AddTraffStatU(int dir, uint32_t ip, uint32_t len)
787 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
795 int64_t traff = tariff->GetTraffByType(up.ConstData()[dir], down.ConstData()[dir]);
796 int64_t threshold = tariff->GetThreshold(dir) * 1024 * 1024;
800 int tt = tariff->GetTraffType();
801 if (tt == TRAFF_UP ||
802 tt == TRAFF_UP_DOWN ||
803 // Check NEW traff data
804 (tt == TRAFF_MAX && dt[dir] > down.ConstData()[dir]))
807 if (traff < threshold &&
808 traff + len >= threshold)
810 // cash = partBeforeThreshold * priceBeforeThreshold +
811 // partAfterThreshold * priceAfterThreshold
812 int64_t before = threshold - traff; // Chunk part before threshold
813 int64_t after = len - before; // Chunk part after threshold
814 dc = tariff->GetPriceWithTraffType(up.ConstData()[dir], // Traff before chunk
815 down.ConstData()[dir],
818 tariff->GetPriceWithTraffType(dt[dir], // Traff after chunk
819 down.ConstData()[dir],
825 dc = tariff->GetPriceWithTraffType(up.ConstData()[dir],
826 down.ConstData()[dir],
831 if (freeMb.ConstData() <= 0) // FreeMb is exhausted
833 else if (freeMb.ConstData() < dc) // FreeMb is partially exhausted
834 cost = dc - freeMb.ConstData();
836 // Direct access to internal data structures via friend-specifier
837 property.stat.freeMb -= dc;
838 property.stat.cash -= cost;
844 sessionUpload[dir] += len;
848 if (!writeFreeMbTraffCost && freeMb.ConstData() >= 0)
851 #ifdef TRAFF_STAT_WITH_PORTS
852 IP_DIR_PAIR idp(ip, dir, port);
854 IP_DIR_PAIR idp(ip, dir);
857 map<IP_DIR_PAIR, STAT_NODE>::iterator lb;
858 lb = traffStat.lower_bound(idp);
859 if (lb == traffStat.end() || lb.first != idp)
862 pair<IP_DIR_PAIR, STAT_NODE>(idp,
863 STAT_NODE(len, 0, cost)));
867 lb->second.cash += cost;
868 lb->second.up += len;
871 //-----------------------------------------------------------------------------
872 #ifdef TRAFF_STAT_WITH_PORTS
873 void USER::AddTraffStatD(int dir, uint32_t ip, uint16_t port, uint32_t len)
875 void USER::AddTraffStatD(int dir, uint32_t ip, uint32_t len)
878 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
886 int64_t traff = tariff->GetTraffByType(up.ConstData()[dir], down.ConstData()[dir]);
887 int64_t threshold = tariff->GetThreshold(dir) * 1024 * 1024;
891 int tt = tariff->GetTraffType();
892 if (tt == TRAFF_DOWN ||
893 tt == TRAFF_UP_DOWN ||
894 // Check NEW traff data
895 (tt == TRAFF_MAX && up.ConstData()[dir] <= dt[dir]))
898 if (traff < threshold &&
899 traff + len >= threshold)
901 // cash = partBeforeThreshold * priceBeforeThreshold +
902 // partAfterThreshold * priceAfterThreshold
903 int64_t before = threshold - traff; // Chunk part before threshold
904 int64_t after = len - before; // Chunk part after threshold
905 dc = tariff->GetPriceWithTraffType(up.ConstData()[dir],
906 down.ConstData()[dir], // Traff before chunk
909 tariff->GetPriceWithTraffType(up.ConstData()[dir],
910 dt[dir], // Traff after chunk
916 dc = tariff->GetPriceWithTraffType(up.ConstData()[dir],
917 down.ConstData()[dir],
922 if (freeMb.ConstData() <= 0) // FreeMb is exhausted
924 else if (freeMb.ConstData() < dc) // FreeMb is partially exhausted
925 cost = dc - freeMb.ConstData();
927 property.stat.freeMb -= dc;
928 property.stat.cash -= cost;
934 sessionDownload[dir] += len;
938 if (!writeFreeMbTraffCost && freeMb.ConstData() >= 0)
941 #ifdef TRAFF_STAT_WITH_PORTS
942 IP_DIR_PAIR idp(ip, dir, port);
944 IP_DIR_PAIR idp(ip, dir);
947 map<IP_DIR_PAIR, STAT_NODE>::iterator lb;
948 lb = traffStat.lower_bound(idp);
949 if (lb == traffStat->end() || lb->first != idp)
951 traffStat->insert(lb,
952 pair<IP_DIR_PAIR, STAT_NODE>(idp,
953 STAT_NODE(0, len, cost)));
957 lb->second.cash += cost;
958 lb->second.down += len;
961 //-----------------------------------------------------------------------------
962 void USER::AddCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
964 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
965 currIP.AddBeforeNotifier(n);
967 //-----------------------------------------------------------------------------
968 void USER::DelCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
970 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
971 currIP.DelBeforeNotifier(n);
973 //-----------------------------------------------------------------------------
974 void USER::AddCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
976 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
977 currIP.AddAfterNotifier(n);
979 //-----------------------------------------------------------------------------
980 void USER::DelCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
982 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
983 currIP.DelAfterNotifier(n);
985 //-----------------------------------------------------------------------------
988 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
990 string scriptOnAdd = settings->GetScriptDir() + "/OnUserAdd";
992 if (access(scriptOnAdd.c_str(), X_OK) == 0)
994 string scriptOnAddParams;
995 strprintf(&scriptOnAddParams,
1000 ScriptExec(scriptOnAddParams);
1004 WriteServLog("Script %s cannot be executed. File not found.", scriptOnAdd.c_str());
1007 //-----------------------------------------------------------------------------
1008 void USER::OnDelete()
1010 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1012 string scriptOnDel = settings->GetScriptDir() + "/OnUserDel";
1014 if (access(scriptOnDel.c_str(), X_OK) == 0)
1016 string scriptOnDelParams;
1017 strprintf(&scriptOnDelParams,
1019 scriptOnDel.c_str(),
1022 ScriptExec(scriptOnDelParams);
1026 WriteServLog("Script %s cannot be executed. File not found.", scriptOnDel.c_str());
1031 //-----------------------------------------------------------------------------
1032 /*void USER::ResetDetailStat()
1034 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1036 traffStatToWrite->erase(traffStatToWrite->begin(), traffStatToWrite->end());
1038 //-----------------------------------------------------------------------------
1039 int USER::WriteDetailStat(bool hard)
1041 /*STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1043 printfd(__FILE__, "USER::WriteDetailedStat(): size = %d\n", traffStatToWrite->size());
1045 if (traffStatToWrite->size() && !disabledDetailStat)
1047 if (store->WriteDetailedStat(traffStatToWrite, lastWriteDeatiledStat, login))
1049 WriteServLog("Cannot write detail stat for user %s.", login.c_str());
1050 WriteServLog("%s", store->GetStrError().c_str());
1053 lastWriteDeatiledStat = lastSwapDeatiledStat;
1055 printfd(__FILE__, "USER::WriteDetailedStat() - queue size = %d\n", traffStatQueue.size());
1057 if (!traffStatQueue.empty())
1059 std::list<std::pair<time_t, TRAFF_STAT> >::iterator it;
1060 for (it = traffStatQueue.begin(); it != traffStatQueue.end(); ++it)
1062 if (store->WriteDetailedStat(it->second, it->first, login))
1064 printfd(__FILE__, "USER::WriteDetailStat() - failed to write detail stat from queue\n");
1065 WriteServLog("Cannot write detail stat from queue (of size %d recs) for user %s.", traffStatQueue.size(), login.c_str());
1066 WriteServLog("%s", store->GetStrError().c_str());
1069 traffStatQueue.erase(it++);
1076 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1080 printfd(__FILE__, "USER::WriteDetailedStat() - size = %d\n", ts.size());
1082 if (ts.size() && !disabledDetailStat)
1084 if (store->WriteDetailedStat(ts, lastWriteDeatiledStat, login))
1086 printfd(__FILE__, "USER::WriteDetailStat() - failed to write current detail stat\n");
1087 WriteServLog("Cannot write detail stat for user %s.", login.c_str());
1088 WriteServLog("%s", store->GetStrError().c_str());
1091 printfd(__FILE__, "USER::WriteDetailStat() - pushing detail stat to queue\n");
1092 traffStatQueue.push_back(std::make_pair(lastWriteDeatiledStat, ts));
1096 lastWriteDeatiledStat = stgTime;
1099 //-----------------------------------------------------------------------------
1100 /*int USER::SwapDetailStat()
1102 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1104 lastSwapDeatiledStat = stgTime;
1105 traffStatToWrite = &traffStatInternal[traffStatInUse % 2];
1106 traffStat = &traffStatInternal[++traffStatInUse % 2];
1110 //-----------------------------------------------------------------------------
1111 double USER::GetPassiveTimePart() const
1113 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1115 static int daysInMonth[12] =
1116 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
1120 tms = localtime(&t);
1122 time_t secMonth = daysInMonth[(tms->tm_mon + 11) % 12] * 24 * 3600; // Previous month
1124 if (tms->tm_year % 4 == 0 && tms->tm_mon == 1)
1127 secMonth += 24 * 3600;
1130 int dt = secMonth - passiveTime;
1135 return double(dt) / (secMonth);
1137 //-----------------------------------------------------------------------------
1138 void USER::SetPassiveTimeAsNewUser()
1140 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1146 int daysCurrMon = DaysInCurrentMonth();
1147 double pt = (tm->tm_mday - 1) / (double)daysCurrMon;
1149 passiveTime = (time_t)(pt * 24 * 3600 * daysCurrMon);
1151 //-----------------------------------------------------------------------------
1152 void USER::MidnightResetSessionStat()
1154 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1158 Disconnect(true, "fake");
1162 //-----------------------------------------------------------------------------
1163 void USER::ProcessNewMonth()
1165 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1169 Disconnect(true, "fake");
1171 DIR_TRAFF zeroTarff;
1184 if (nextTariff.ConstData() != "")
1187 nt = tariffs->FindByName(nextTariff);
1190 WriteServLog("Cannot change tariff for user %s. Tariff %s not exist.",
1191 login.c_str(), property.tariffName.Get().c_str());
1195 property.tariffName.Set(nextTariff, sysAdmin, login, store);
1202 //-----------------------------------------------------------------------------
1203 void USER::ProcessDayFeeSpread()
1205 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1207 if (passive.ConstData())
1210 double f = tariff->GetFee() / DaysInCurrentMonth();
1216 property.cash.Set(c - f, sysAdmin, login, store, "Subscriber fee charge");
1219 //-----------------------------------------------------------------------------
1220 void USER::ProcessDayFee()
1222 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1224 double passiveTimePart = 1.0;
1225 if (!settings->GetFullFee())
1227 passiveTimePart = GetPassiveTimePart();
1231 if (passive.ConstData())
1233 printfd(__FILE__, "Don't charge fee `cause we are passive\n");
1237 double f = tariff->GetFee() * passiveTimePart;
1245 printfd(__FILE__, "login: %8s Fee=%f PassiveTimePart=%f fee=%f\n",
1250 property.cash.Set(c - f, sysAdmin, login, store, "Subscriber fee charge");
1252 //-----------------------------------------------------------------------------
1253 void USER::SetPrepaidTraff()
1255 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1257 property.freeMb.Set(tariff->GetFree(), sysAdmin, login, store, "Prepaid traffic");
1259 //-----------------------------------------------------------------------------
1260 int USER::AddMessage(STG_MSG * msg)
1262 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1264 if (SendMessage(*msg) == 0)
1266 if (msg->header.repeat > 0)
1268 msg->header.repeat--;
1270 //TODO: gcc v. 4.x generate ICE on x86_64
1271 msg->header.lastSendTime = time(NULL);
1273 msg->header.lastSendTime = stgTime;
1275 if (store->AddMessage(msg, login))
1277 errorStr = store->GetStrError();
1278 STG_LOGGER & WriteServLog = GetStgLogger();
1279 WriteServLog("Error adding message %s", errorStr.c_str());
1280 WriteServLog("%s", store->GetStrError().c_str());
1287 if (store->AddMessage(msg, login))
1289 errorStr = store->GetStrError();
1290 STG_LOGGER & WriteServLog = GetStgLogger();
1291 WriteServLog("Error adding message %s", errorStr.c_str());
1292 WriteServLog("%s", store->GetStrError().c_str());
1298 //-----------------------------------------------------------------------------
1299 int USER::SendMessage(const STG_MSG & msg)
1301 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1303 if (authorizedBy.empty())
1309 set<const BASE_AUTH*>::iterator it;
1311 it = authorizedBy.begin();
1312 while (it != authorizedBy.end())
1314 if ((*it)->SendMessage(msg, currIP) == 0)
1320 //-----------------------------------------------------------------------------
1321 int USER::ScanMessage()
1323 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1325 vector<STG_MSG_HDR> hdrsList;
1327 if (store->GetMessageHdrs(&hdrsList, login))
1329 printfd(__FILE__, "Error GetMessageHdrs %s\n", store->GetStrError().c_str());
1333 for (unsigned i = 0; i < hdrsList.size(); i++)
1336 if (hdrsList[i].lastSendTime + hdrsList[i].repeatPeriod * 60 < (unsigned)stgTime)
1339 if (store->GetMessage(hdrsList[i].id, &msg, login) == 0)
1341 if (SendMessage(msg) == 0)
1343 msg.header.repeat--;
1344 if (msg.header.repeat < 0)
1346 printfd(__FILE__, "DelMessage\n");
1347 store->DelMessage(hdrsList[i].id, login);
1352 //TODO: gcc v. 4.x generate ICE on x86_64
1353 msg.header.lastSendTime = time(NULL);
1355 msg.header.lastSendTime = stgTime;
1357 if (store->EditMessage(msg, login))
1359 printfd(__FILE__, "EditMessage Error %s\n", store->GetStrError().c_str());
1366 WriteServLog("Cannot get message for user %s.", login.c_str());
1367 WriteServLog("%s", store->GetStrError().c_str());
1373 //-----------------------------------------------------------------------------
1374 //-----------------------------------------------------------------------------
1375 //-----------------------------------------------------------------------------
1376 void CHG_PASSIVE_NOTIFIER::Notify(const int & oldPassive, const int & newPassive)
1378 if (newPassive && !oldPassive)
1379 user->property.cash.Set(user->cash - user->tariff->GetPassiveCost(),
1385 //-----------------------------------------------------------------------------
1386 void CHG_TARIFF_NOTIFIER::Notify(const string &, const string & newTariff)
1388 user->tariff = user->tariffs->FindByName(newTariff);
1390 //-----------------------------------------------------------------------------
1391 void CHG_CASH_NOTIFIER::Notify(const double & oldCash, const double & newCash)
1393 user->lastCashAddTime = *const_cast<time_t *>(&stgTime);
1394 user->lastCashAdd = newCash - oldCash;
1396 //-----------------------------------------------------------------------------
1397 void CHG_IP_NOTIFIER::Notify(const uint32_t & from, const uint32_t & to)
1399 printfd(__FILE__, "Change IP from %s to %s\n", inet_ntostring(from).c_str(), inet_ntostring(to).c_str());
1401 if (user->connected)
1402 user->Disconnect(false, "Change IP");
1404 if (user->IsInetable())
1405 user->Connect(false);
1407 //-----------------------------------------------------------------------------