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;
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),
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())
861 traffStat->insert(lb,
862 pair<IP_DIR_PAIR, STAT_NODE>(idp,
863 STAT_NODE(len, 0, cost)));
866 if (lb->first.dir == dir && lb->first.ip == ip)
868 lb->second.cash += cost;
869 lb->second.up += len;
873 traffStat->insert(lb,
874 pair<IP_DIR_PAIR, STAT_NODE>(idp,
875 STAT_NODE(len, 0, cost)));
878 //-----------------------------------------------------------------------------
879 #ifdef TRAFF_STAT_WITH_PORTS
880 void USER::AddTraffStatD(int dir, uint32_t ip, uint16_t port, uint32_t len)
882 void USER::AddTraffStatD(int dir, uint32_t ip, uint32_t len)
885 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
893 int64_t traff = tariff->GetTraffByType(up.ConstData()[dir], down.ConstData()[dir]);
894 int64_t threshold = tariff->GetThreshold(dir) * 1024 * 1024;
898 int tt = tariff->GetTraffType();
899 if (tt == TRAFF_DOWN ||
900 tt == TRAFF_UP_DOWN ||
901 // Check NEW traff data
902 (tt == TRAFF_MAX && up.ConstData()[dir] <= dt[dir]))
905 if (traff < threshold &&
906 traff + len >= threshold)
908 // cash = partBeforeThreshold * priceBeforeThreshold +
909 // partAfterThreshold * priceAfterThreshold
910 int64_t before = threshold - traff; // Chunk part before threshold
911 int64_t after = len - before; // Chunk part after threshold
912 dc = tariff->GetPriceWithTraffType(up.ConstData()[dir],
913 down.ConstData()[dir], // Traff before chunk
916 tariff->GetPriceWithTraffType(up.ConstData()[dir],
917 dt[dir], // Traff after chunk
923 dc = tariff->GetPriceWithTraffType(up.ConstData()[dir],
924 down.ConstData()[dir],
929 if (freeMb.ConstData() <= 0) // FreeMb is exhausted
931 else if (freeMb.ConstData() < dc) // FreeMb is partially exhausted
932 cost = dc - freeMb.ConstData();
934 property.stat.freeMb -= dc;
935 property.stat.cash -= cost;
941 sessionDownload[dir] += len;
945 if (!writeFreeMbTraffCost && freeMb.ConstData() >= 0)
948 #ifdef TRAFF_STAT_WITH_PORTS
949 IP_DIR_PAIR idp(ip, dir, port);
951 IP_DIR_PAIR idp(ip, dir);
954 map<IP_DIR_PAIR, STAT_NODE>::iterator lb;
955 lb = traffStat->lower_bound(idp);
956 if (lb == traffStat->end())
958 traffStat->insert(lb,
959 pair<IP_DIR_PAIR, STAT_NODE>(idp,
960 STAT_NODE(0, len, cost)));
963 if (lb->first.dir == dir && lb->first.ip == ip)
965 lb->second.cash += cost;
966 lb->second.down += len;
970 traffStat->insert(lb,
971 pair<IP_DIR_PAIR, STAT_NODE>(idp,
972 STAT_NODE(0, len, cost)));
975 //-----------------------------------------------------------------------------
976 void USER::AddCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
978 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
979 currIP.AddBeforeNotifier(n);
981 //-----------------------------------------------------------------------------
982 void USER::DelCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
984 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
985 currIP.DelBeforeNotifier(n);
987 //-----------------------------------------------------------------------------
988 void USER::AddCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
990 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
991 currIP.AddAfterNotifier(n);
993 //-----------------------------------------------------------------------------
994 void USER::DelCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
996 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
997 currIP.DelAfterNotifier(n);
999 //-----------------------------------------------------------------------------
1002 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1004 string scriptOnAdd = settings->GetScriptDir() + "/OnUserAdd";
1006 if (access(scriptOnAdd.c_str(), X_OK) == 0)
1008 string scriptOnAddParams;
1009 strprintf(&scriptOnAddParams,
1011 scriptOnAdd.c_str(),
1014 ScriptExec(scriptOnAddParams);
1018 WriteServLog("Script %s cannot be executed. File not found.", scriptOnAdd.c_str());
1021 //-----------------------------------------------------------------------------
1022 void USER::OnDelete()
1024 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1026 string scriptOnDel = settings->GetScriptDir() + "/OnUserDel";
1028 if (access(scriptOnDel.c_str(), X_OK) == 0)
1030 string scriptOnDelParams;
1031 strprintf(&scriptOnDelParams,
1033 scriptOnDel.c_str(),
1036 ScriptExec(scriptOnDelParams);
1040 WriteServLog("Script %s cannot be executed. File not found.", scriptOnDel.c_str());
1045 //-----------------------------------------------------------------------------
1046 void USER::ResetDetailStat()
1048 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1050 traffStatToWrite->erase(traffStatToWrite->begin(), traffStatToWrite->end());
1052 //-----------------------------------------------------------------------------
1053 int USER::WriteDetailStat()
1055 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1057 printfd(__FILE__, "USER::WriteDetailedStat(): size = %d\n", traffStatToWrite->size());
1059 if (traffStatToWrite->size() && !disabledDetailStat)
1061 if (store->WriteDetailedStat(traffStatToWrite, lastWriteDeatiledStat, login))
1063 WriteServLog("Cannot write detail stat for user %s.", login.c_str());
1064 WriteServLog("%s", store->GetStrError().c_str());
1067 lastWriteDeatiledStat = lastSwapDeatiledStat;
1070 //-----------------------------------------------------------------------------
1071 int USER::SwapDetailStat()
1073 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1075 lastSwapDeatiledStat = stgTime;
1076 traffStatToWrite = &traffStatInternal[traffStatInUse % 2];
1077 traffStat = &traffStatInternal[++traffStatInUse % 2];
1081 //-----------------------------------------------------------------------------
1082 double USER::GetPassiveTimePart() const
1084 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1086 static int daysInMonth[12] =
1087 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
1091 tms = localtime(&t);
1093 time_t secMonth = daysInMonth[(tms->tm_mon + 11) % 12] * 24 * 3600; // Previous month
1095 if (tms->tm_year % 4 == 0 && tms->tm_mon == 1)
1098 secMonth += 24 * 3600;
1101 int dt = secMonth - passiveTime;
1106 return double(dt) / (secMonth);
1108 //-----------------------------------------------------------------------------
1109 void USER::SetPassiveTimeAsNewUser()
1111 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1117 int daysCurrMon = DaysInCurrentMonth();
1118 double pt = (tm->tm_mday - 1) / (double)daysCurrMon;
1120 passiveTime = (time_t)(pt * 24 * 3600 * daysCurrMon);
1122 //-----------------------------------------------------------------------------
1123 void USER::MidnightResetSessionStat()
1125 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1129 Disconnect(true, "fake");
1133 //-----------------------------------------------------------------------------
1134 void USER::ProcessNewMonth()
1136 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1140 Disconnect(true, "fake");
1142 DIR_TRAFF zeroTarff;
1155 if (nextTariff.ConstData() != "")
1158 nt = tariffs->FindByName(nextTariff);
1161 WriteServLog("Cannot change tariff for user %s. Tariff %s not exist.",
1162 login.c_str(), property.tariffName.Get().c_str());
1166 property.tariffName.Set(nextTariff, sysAdmin, login, store);
1173 //-----------------------------------------------------------------------------
1174 void USER::ProcessDayFeeSpread()
1176 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1178 if (passive.ConstData())
1181 double f = tariff->GetFee() / DaysInCurrentMonth();
1187 property.cash.Set(c - f, sysAdmin, login, store, "Subscriber fee charge");
1190 //-----------------------------------------------------------------------------
1191 void USER::ProcessDayFee()
1193 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1195 double passiveTimePart = 1.0;
1196 if (!settings->GetFullFee())
1198 passiveTimePart = GetPassiveTimePart();
1202 if (passive.ConstData())
1204 printfd(__FILE__, "Don't charge fee `cause we are passive\n");
1208 double f = tariff->GetFee() * passiveTimePart;
1216 printfd(__FILE__, "login: %8s Fee=%f PassiveTimePart=%f fee=%f\n",
1221 property.cash.Set(c - f, sysAdmin, login, store, "Subscriber fee charge");
1223 //-----------------------------------------------------------------------------
1224 void USER::SetPrepaidTraff()
1226 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1228 property.freeMb.Set(tariff->GetFree(), sysAdmin, login, store, "Prepaid traffic");
1230 //-----------------------------------------------------------------------------
1231 int USER::AddMessage(STG_MSG * msg)
1233 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1235 if (SendMessage(*msg) == 0)
1237 if (msg->header.repeat > 0)
1239 msg->header.repeat--;
1241 //TODO: gcc v. 4.x generate ICE on x86_64
1242 msg->header.lastSendTime = time(NULL);
1244 msg->header.lastSendTime = stgTime;
1246 if (store->AddMessage(msg, login))
1248 errorStr = store->GetStrError();
1249 STG_LOGGER & WriteServLog = GetStgLogger();
1250 WriteServLog("Error adding message %s", errorStr.c_str());
1251 WriteServLog("%s", store->GetStrError().c_str());
1258 if (store->AddMessage(msg, login))
1260 errorStr = store->GetStrError();
1261 STG_LOGGER & WriteServLog = GetStgLogger();
1262 WriteServLog("Error adding message %s", errorStr.c_str());
1263 WriteServLog("%s", store->GetStrError().c_str());
1269 //-----------------------------------------------------------------------------
1270 int USER::SendMessage(const STG_MSG & msg)
1272 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1274 if (authorizedBy.empty())
1280 set<const BASE_AUTH*>::iterator it;
1282 it = authorizedBy.begin();
1283 while (it != authorizedBy.end())
1285 if ((*it)->SendMessage(msg, currIP) == 0)
1291 //-----------------------------------------------------------------------------
1292 int USER::ScanMessage()
1294 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1296 vector<STG_MSG_HDR> hdrsList;
1298 if (store->GetMessageHdrs(&hdrsList, login))
1300 printfd(__FILE__, "Error GetMessageHdrs %s\n", store->GetStrError().c_str());
1304 for (unsigned i = 0; i < hdrsList.size(); i++)
1307 if (hdrsList[i].lastSendTime + hdrsList[i].repeatPeriod * 60 < (unsigned)stgTime)
1310 if (store->GetMessage(hdrsList[i].id, &msg, login) == 0)
1312 if (SendMessage(msg) == 0)
1314 msg.header.repeat--;
1315 if (msg.header.repeat < 0)
1317 printfd(__FILE__, "DelMessage\n");
1318 store->DelMessage(hdrsList[i].id, login);
1323 //TODO: gcc v. 4.x generate ICE on x86_64
1324 msg.header.lastSendTime = time(NULL);
1326 msg.header.lastSendTime = stgTime;
1328 if (store->EditMessage(msg, login))
1330 printfd(__FILE__, "EditMessage Error %s\n", store->GetStrError().c_str());
1337 WriteServLog("Cannot get message for user %s.", login.c_str());
1338 WriteServLog("%s", store->GetStrError().c_str());
1344 //-----------------------------------------------------------------------------
1345 //-----------------------------------------------------------------------------
1346 //-----------------------------------------------------------------------------
1347 void CHG_PASSIVE_NOTIFIER::Notify(const int & oldPassive, const int & newPassive)
1349 if (newPassive && !oldPassive)
1350 user->property.cash.Set(user->cash - user->tariff->GetPassiveCost(),
1356 //-----------------------------------------------------------------------------
1357 void CHG_TARIFF_NOTIFIER::Notify(const string &, const string & newTariff)
1359 user->tariff = user->tariffs->FindByName(newTariff);
1361 //-----------------------------------------------------------------------------
1362 void CHG_CASH_NOTIFIER::Notify(const double & oldCash, const double & newCash)
1364 user->lastCashAddTime = *const_cast<time_t *>(&stgTime);
1365 user->lastCashAdd = newCash - oldCash;
1367 //-----------------------------------------------------------------------------
1368 void CHG_IP_NOTIFIER::Notify(const uint32_t & from, const uint32_t & to)
1370 printfd(__FILE__, "Change IP from %s to %s\n", inet_ntostring(from).c_str(), inet_ntostring(to).c_str());
1372 user->Disconnect(false, "Change IP");
1374 user->Connect(false);
1376 //-----------------------------------------------------------------------------