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
18 * Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
19 * Author : Maxim Mamontov <faust@stargazer.dp.ua>
24 $Date: 2010/04/16 12:30:37 $
36 #include "ur_functor.h"
37 #include "send_functor.h"
38 #include "stg_locker.h"
39 #include "user_property.h"
41 extern volatile const time_t stgTime;
43 #define RS_MAX_ROUTERS (100)
45 //-----------------------------------------------------------------------------
46 //-----------------------------------------------------------------------------
47 //-----------------------------------------------------------------------------
55 : rs(new REMOTE_SCRIPT())
63 REMOTE_SCRIPT * GetPlugin()
68 //-----------------------------------------------------------------------------
69 //-----------------------------------------------------------------------------
70 //-----------------------------------------------------------------------------
72 //-----------------------------------------------------------------------------
73 //-----------------------------------------------------------------------------
74 //-----------------------------------------------------------------------------
77 return rsc.GetPlugin();
79 //-----------------------------------------------------------------------------
80 //-----------------------------------------------------------------------------
81 //-----------------------------------------------------------------------------
87 //-----------------------------------------------------------------------------
88 RS_USER::RS_USER(const std::vector<uint32_t> & r, USER_PTR it)
95 //-----------------------------------------------------------------------------
96 RS_SETTINGS::RS_SETTINGS()
101 //-----------------------------------------------------------------------------
102 int RS_SETTINGS::ParseIntInRange(const string & str, int min, int max, int * val)
104 if (str2x(str.c_str(), *val))
106 errorStr = "Incorrect value \'" + str + "\'.";
109 if (*val < min || *val > max)
111 errorStr = "Value \'" + str + "\' out of range.";
116 //-----------------------------------------------------------------------------
117 int RS_SETTINGS::ParseSettings(const MODULE_SETTINGS & s)
121 vector<PARAM_VALUE>::const_iterator pvi;
123 ///////////////////////////
125 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
126 if (pvi == s.moduleParams.end())
128 errorStr = "Parameter \'Port\' not found.";
129 printfd(__FILE__, "Parameter 'Port' not found\n");
132 if (ParseIntInRange(pvi->value[0], 2, 65535, &p))
134 errorStr = "Cannot parse parameter \'Port\': " + errorStr;
135 printfd(__FILE__, "Cannot parse parameter 'Port'\n");
139 ///////////////////////////
140 pv.param = "SendPeriod";
141 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
142 if (pvi == s.moduleParams.end())
144 errorStr = "Parameter \'SendPeriod\' not found.";
145 printfd(__FILE__, "Parameter 'SendPeriod' not found\n");
149 if (ParseIntInRange(pvi->value[0], 5, 600, &sendPeriod))
151 errorStr = "Cannot parse parameter \'SendPeriod\': " + errorStr;
152 printfd(__FILE__, "Cannot parse parameter 'SendPeriod'\n");
155 ///////////////////////////
156 pv.param = "UserParams";
157 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
158 if (pvi == s.moduleParams.end())
160 errorStr = "Parameter \'UserParams\' not found.";
161 printfd(__FILE__, "Parameter 'UserParams' not found\n");
164 userParams = pvi->value;
165 ///////////////////////////
166 pv.param = "Password";
167 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
168 if (pvi == s.moduleParams.end())
170 errorStr = "Parameter \'Password\' not found.";
171 printfd(__FILE__, "Parameter 'Password' not found\n");
174 password = pvi->value[0];
175 ///////////////////////////
176 pv.param = "SubnetFile";
177 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
178 if (pvi == s.moduleParams.end())
180 errorStr = "Parameter \'SubnetFile\' not found.";
181 printfd(__FILE__, "Parameter 'SubnetFile' not found\n");
184 subnetFile = pvi->value[0];
186 NRMapParser nrMapParser;
188 if (nrMapParser.ReadFile(subnetFile))
190 errorStr = nrMapParser.GetErrorStr();
194 netRouters = nrMapParser.GetMap();
196 if (netRouters.empty())
198 errorStr = "Parameter(s) \'Subnet*\' not found.";
199 printfd(__FILE__, "Parameter(s) 'Subnet*' not found\n");
205 //-----------------------------------------------------------------------------
206 //-----------------------------------------------------------------------------
207 //-----------------------------------------------------------------------------
208 REMOTE_SCRIPT::REMOTE_SCRIPT()
215 onAddUserNotifier(*this),
216 onDelUserNotifier(*this)
218 pthread_mutex_init(&mutex, NULL);
220 //-----------------------------------------------------------------------------
221 REMOTE_SCRIPT::~REMOTE_SCRIPT()
223 pthread_mutex_destroy(&mutex);
225 //-----------------------------------------------------------------------------
226 void * REMOTE_SCRIPT::Run(void * d)
228 REMOTE_SCRIPT * rs = static_cast<REMOTE_SCRIPT *>(d);
230 rs->isRunning = true;
238 rs->isRunning = false;
241 //-----------------------------------------------------------------------------
242 int REMOTE_SCRIPT::ParseSettings()
244 int ret = rsSettings.ParseSettings(settings);
246 errorStr = rsSettings.GetStrError();
248 sendPeriod = rsSettings.GetSendPeriod();
249 halfPeriod = sendPeriod / 2;
253 //-----------------------------------------------------------------------------
254 int REMOTE_SCRIPT::Start()
256 netRouters = rsSettings.GetSubnetsMap();
258 InitEncrypt(&ctx, rsSettings.GetPassword());
260 //onAddUserNotifier.SetRemoteScript(this);
261 //onDelUserNotifier.SetRemoteScript(this);
263 users->AddNotifierUserAdd(&onAddUserNotifier);
264 users->AddNotifierUserDel(&onDelUserNotifier);
280 if (pthread_create(&thread, NULL, Run, this))
282 errorStr = "Cannot create thread.";
283 printfd(__FILE__, "Cannot create thread\n");
291 //-----------------------------------------------------------------------------
292 int REMOTE_SCRIPT::Stop()
300 authorizedUsers.begin(),
301 authorizedUsers.end(),
302 DisconnectUser(*this)
309 //5 seconds to thread stops itself
310 for (int i = 0; i < 25 && isRunning; i++)
315 //after 5 seconds waiting thread still running. now killing it
318 if (pthread_kill(thread, SIGINT))
320 errorStr = "Cannot kill thread.";
321 printfd(__FILE__, "Cannot kill thread\n");
324 printfd(__FILE__, "REMOTE_SCRIPT killed Run\n");
328 users->DelNotifierUserDel(&onDelUserNotifier);
329 users->DelNotifierUserAdd(&onAddUserNotifier);
333 //-----------------------------------------------------------------------------
334 int REMOTE_SCRIPT::Reload()
336 NRMapParser nrMapParser;
338 if (nrMapParser.ReadFile(rsSettings.GetMapFileName()))
340 errorStr = nrMapParser.GetErrorStr();
345 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
347 printfd(__FILE__, "REMOTE_SCRIPT::Reload()\n");
349 netRouters = nrMapParser.GetMap();
352 std::for_each(authorizedUsers.begin(),
353 authorizedUsers.end(),
354 UpdateRouter(*this));
358 //-----------------------------------------------------------------------------
359 bool REMOTE_SCRIPT::PrepareNet()
361 sock = socket(AF_INET, SOCK_DGRAM, 0);
365 errorStr = "Cannot create socket.";
366 printfd(__FILE__, "Cannot create socket\n");
372 //-----------------------------------------------------------------------------
373 bool REMOTE_SCRIPT::FinalizeNet()
378 //-----------------------------------------------------------------------------
379 void REMOTE_SCRIPT::PeriodicSend()
381 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
383 map<uint32_t, RS_USER>::iterator it(authorizedUsers.begin());
384 while (it != authorizedUsers.end())
386 if (difftime(stgTime, it->second.lastSentTime) - (rand() % halfPeriod) > sendPeriod)
387 //if (stgTime - it->second.lastSentTime > sendPeriod)
389 Send(it->first, it->second);
394 //-----------------------------------------------------------------------------
395 bool REMOTE_SCRIPT::PreparePacket(char * buf, size_t bufSize, uint32_t ip, RS_USER & rsu, bool forceDisconnect) const
397 RS_PACKET_HEADER packetHead;
399 memset(packetHead.padding, 0, sizeof(packetHead.padding));
400 strcpy((char*)packetHead.magic, RS_ID);
401 packetHead.protoVer[0] = '0';
402 packetHead.protoVer[1] = '2';
405 packetHead.packetType = RS_DISCONNECT_PACKET;
409 if (rsu.shortPacketsCount % MAX_SHORT_PCKT == 0)
412 packetHead.packetType = rsu.user->IsInetable() ? RS_CONNECT_PACKET : RS_DISCONNECT_PACKET;
417 packetHead.packetType = rsu.user->IsInetable() ? RS_ALIVE_PACKET : RS_DISCONNECT_PACKET;
420 rsu.shortPacketsCount++;
421 rsu.lastSentTime = stgTime;
423 packetHead.ip = htonl(ip);
424 packetHead.id = htonl(rsu.user->GetID());
425 strncpy((char*)packetHead.login, rsu.user->GetLogin().c_str(), RS_LOGIN_LEN);
426 packetHead.login[RS_LOGIN_LEN - 1] = 0;
428 memcpy(buf, &packetHead, sizeof(packetHead));
430 if (packetHead.packetType == RS_ALIVE_PACKET)
435 RS_PACKET_TAIL packetTail;
437 memset(packetTail.padding, 0, sizeof(packetTail.padding));
438 strcpy((char*)packetTail.magic, RS_ID);
439 vector<string>::const_iterator it;
441 for(it = rsSettings.GetUserParams().begin();
442 it != rsSettings.GetUserParams().end();
445 std::string parameter(GetUserParam(rsu.user, *it));
446 if (params.length() + parameter.length() > RS_PARAMS_LEN - 1)
448 params += parameter + " ";
450 strncpy((char *)packetTail.params, params.c_str(), RS_PARAMS_LEN);
451 packetTail.params[RS_PARAMS_LEN - 1] = 0;
453 assert(sizeof(packetHead) + sizeof(packetTail) <= bufSize && "Insufficient buffer space");
455 Encrypt(&ctx, buf + sizeof(packetHead), (char *)&packetTail, sizeof(packetTail) / 8);
459 //-----------------------------------------------------------------------------
460 bool REMOTE_SCRIPT::Send(uint32_t ip, RS_USER & rsu, bool forceDisconnect) const
462 char buffer[RS_MAX_PACKET_LEN];
464 memset(buffer, 0, sizeof(buffer));
466 if (PreparePacket(buffer, sizeof(buffer), ip, rsu, forceDisconnect))
468 printfd(__FILE__, "REMOTE_SCRIPT::Send() - Invalid packet length!\n");
475 PacketSender(sock, buffer, sizeof(buffer), htons(rsSettings.GetPort()))
480 //-----------------------------------------------------------------------------
481 bool REMOTE_SCRIPT::SendDirect(uint32_t ip, RS_USER & rsu, uint32_t routerIP, bool forceDisconnect) const
483 char buffer[RS_MAX_PACKET_LEN];
485 if (PreparePacket(buffer, sizeof(buffer), ip, rsu, forceDisconnect))
487 printfd(__FILE__, "REMOTE_SCRIPT::SendDirect() - Invalid packet length!\n");
491 struct sockaddr_in sendAddr;
493 sendAddr.sin_family = AF_INET;
494 sendAddr.sin_port = htons(rsSettings.GetPort());
495 sendAddr.sin_addr.s_addr = routerIP;
497 int res = sendto(sock, buffer, sizeof(buffer), 0, (struct sockaddr *)&sendAddr, sizeof(sendAddr));
499 return (res != sizeof(buffer));
501 //-----------------------------------------------------------------------------
502 bool REMOTE_SCRIPT::GetUsers()
506 int h = users->OpenSearch();
509 errorStr = "users->OpenSearch() error.";
510 printfd(__FILE__, "OpenSearch() error\n");
514 while (!users->SearchNext(h, &u))
519 users->CloseSearch(h);
522 //-----------------------------------------------------------------------------
523 void REMOTE_SCRIPT::ChangedIP(USER_PTR u, uint32_t oldIP, uint32_t newIP)
526 * When ip changes process looks like:
532 RS_USER rsu(IP2Routers(newIP), u);
535 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
536 authorizedUsers[newIP] = rsu;
540 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
541 const map<uint32_t, RS_USER>::iterator it(
542 authorizedUsers.find(oldIP)
544 if (it != authorizedUsers.end())
546 Send(oldIP, it->second, true);
547 authorizedUsers.erase(it);
551 //-----------------------------------------------------------------------------
552 std::vector<uint32_t> REMOTE_SCRIPT::IP2Routers(uint32_t ip)
554 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
555 for (size_t i = 0; i < netRouters.size(); ++i)
557 if ((ip & netRouters[i].subnetMask) == (netRouters[i].subnetIP & netRouters[i].subnetMask))
559 return netRouters[i].routers;
562 return std::vector<uint32_t>();
564 //-----------------------------------------------------------------------------
565 string REMOTE_SCRIPT::GetUserParam(USER_PTR u, const string & paramName) const
568 if (strcasecmp(paramName.c_str(), "cash") == 0)
569 strprintf(&value, "%f", u->GetProperty().cash.Get());
571 if (strcasecmp(paramName.c_str(), "freeMb") == 0)
572 strprintf(&value, "%f", u->GetProperty().freeMb.Get());
574 if (strcasecmp(paramName.c_str(), "passive") == 0)
575 strprintf(&value, "%d", u->GetProperty().passive.Get());
577 if (strcasecmp(paramName.c_str(), "disabled") == 0)
578 strprintf(&value, "%d", u->GetProperty().disabled.Get());
580 if (strcasecmp(paramName.c_str(), "alwaysOnline") == 0)
581 strprintf(&value, "%d", u->GetProperty().alwaysOnline.Get());
583 if (strcasecmp(paramName.c_str(), "tariffName") == 0 ||
584 strcasecmp(paramName.c_str(), "tariff") == 0)
585 value = "\"" + u->GetProperty().tariffName.Get() + "\"";
587 if (strcasecmp(paramName.c_str(), "nextTariff") == 0)
588 value = "\"" + u->GetProperty().nextTariff.Get() + "\"";
590 if (strcasecmp(paramName.c_str(), "address") == 0)
591 value = "\"" + u->GetProperty().address.Get() + "\"";
593 if (strcasecmp(paramName.c_str(), "note") == 0)
594 value = "\"" + u->GetProperty().note.Get() + "\"";
596 if (strcasecmp(paramName.c_str(), "group") == 0)
597 value = "\"" + u->GetProperty().group.Get() + "\"";
599 if (strcasecmp(paramName.c_str(), "email") == 0)
600 value = "\"" + u->GetProperty().email.Get() + "\"";
602 if (strcasecmp(paramName.c_str(), "realName") == 0)
603 value = "\"" + u->GetProperty().realName.Get() + "\"";
605 if (strcasecmp(paramName.c_str(), "credit") == 0)
606 strprintf(&value, "%f", u->GetProperty().credit.Get());
608 if (strcasecmp(paramName.c_str(), "userdata0") == 0)
609 value = "\"" + u->GetProperty().userdata0.Get() + "\"";
611 if (strcasecmp(paramName.c_str(), "userdata1") == 0)
612 value = "\"" + u->GetProperty().userdata1.Get() + "\"";
614 if (strcasecmp(paramName.c_str(), "userdata2") == 0)
615 value = "\"" + u->GetProperty().userdata2.Get() + "\"";
617 if (strcasecmp(paramName.c_str(), "userdata3") == 0)
618 value = "\"" + u->GetProperty().userdata3.Get() + "\"";
620 if (strcasecmp(paramName.c_str(), "userdata4") == 0)
621 value = "\"" + u->GetProperty().userdata4.Get() + "\"";
623 if (strcasecmp(paramName.c_str(), "userdata5") == 0)
624 value = "\"" + u->GetProperty().userdata5.Get() + "\"";
626 if (strcasecmp(paramName.c_str(), "userdata6") == 0)
627 value = "\"" + u->GetProperty().userdata6.Get() + "\"";
629 if (strcasecmp(paramName.c_str(), "userdata7") == 0)
630 value = "\"" + u->GetProperty().userdata7.Get() + "\"";
632 if (strcasecmp(paramName.c_str(), "userdata8") == 0)
633 value = "\"" + u->GetProperty().userdata8.Get() + "\"";
635 if (strcasecmp(paramName.c_str(), "userdata9") == 0)
636 value = "\"" + u->GetProperty().userdata9.Get() + "\"";
638 if (strcasecmp(paramName.c_str(), "enabledDirs") == 0)
639 value = u->GetEnabledDirs();
641 printfd(__FILE__, "Unknown value name: %s\n", paramName.c_str());
644 //-----------------------------------------------------------------------------
645 void REMOTE_SCRIPT::SetUserNotifier(USER_PTR u)
647 RS_CHG_AFTER_NOTIFIER<uint32_t> afterChgIPNotifier(*this, u);
649 afterChgIPNotifierList.push_front(afterChgIPNotifier);
651 u->AddCurrIPAfterNotifier(&(*afterChgIPNotifierList.begin()));
653 //-----------------------------------------------------------------------------
654 void REMOTE_SCRIPT::UnSetUserNotifier(USER_PTR u)
656 list<RS_CHG_AFTER_NOTIFIER<uint32_t> >::iterator ipAIter;
657 std::list<list<RS_CHG_AFTER_NOTIFIER<uint32_t> >::iterator> toErase;
659 for (ipAIter = afterChgIPNotifierList.begin(); ipAIter != afterChgIPNotifierList.end(); ++ipAIter)
661 if (ipAIter->GetUser() == u)
663 u->DelCurrIPAfterNotifier(&(*ipAIter));
664 toErase.push_back(ipAIter);
668 std::list<list<RS_CHG_AFTER_NOTIFIER<uint32_t> >::iterator>::iterator eIter;
670 for (eIter = toErase.begin(); eIter != toErase.end(); ++eIter)
672 afterChgIPNotifierList.erase(*eIter);
675 //-----------------------------------------------------------------------------
676 template <typename varParamType>
677 void RS_CHG_AFTER_NOTIFIER<varParamType>::Notify(const varParamType & oldValue, const varParamType & newValue)
679 rs.ChangedIP(user, oldValue, newValue);
681 //-----------------------------------------------------------------------------
682 void REMOTE_SCRIPT::InitEncrypt(BLOWFISH_CTX * ctx, const string & password) const
684 unsigned char keyL[PASSWD_LEN]; // Пароль для шифровки
685 memset(keyL, 0, PASSWD_LEN);
686 strncpy((char *)keyL, password.c_str(), PASSWD_LEN);
687 Blowfish_Init(ctx, keyL, PASSWD_LEN);
689 //-----------------------------------------------------------------------------
690 void REMOTE_SCRIPT::Encrypt(BLOWFISH_CTX * ctx, char * dst, const char * src, size_t len8) const
693 memcpy(dst, src, len8 * 8);
694 for (size_t i = 0; i < len8; ++i)
695 Blowfish_Encrypt(ctx, (uint32_t *)(dst + i * 8), (uint32_t *)(dst + i * 8 + 4));
697 //-----------------------------------------------------------------------------