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"
39 extern volatile const time_t stgTime;
41 #define RS_MAX_ROUTERS (100)
43 //-----------------------------------------------------------------------------
44 //-----------------------------------------------------------------------------
45 //-----------------------------------------------------------------------------
53 : rs(new REMOTE_SCRIPT())
61 REMOTE_SCRIPT * GetPlugin()
66 //-----------------------------------------------------------------------------
67 //-----------------------------------------------------------------------------
68 //-----------------------------------------------------------------------------
70 //-----------------------------------------------------------------------------
71 //-----------------------------------------------------------------------------
72 //-----------------------------------------------------------------------------
73 BASE_PLUGIN * GetPlugin()
75 return rsc.GetPlugin();
77 //-----------------------------------------------------------------------------
78 //-----------------------------------------------------------------------------
79 //-----------------------------------------------------------------------------
85 //-----------------------------------------------------------------------------
86 RS_USER::RS_USER(const std::vector<uint32_t> & r, user_iter it)
93 //-----------------------------------------------------------------------------
94 RS_SETTINGS::RS_SETTINGS()
99 //-----------------------------------------------------------------------------
100 int RS_SETTINGS::ParseIntInRange(const string & str, int min, int max, int * val)
102 if (str2x(str.c_str(), *val))
104 errorStr = "Incorrect value \'" + str + "\'.";
107 if (*val < min || *val > max)
109 errorStr = "Value \'" + str + "\' out of range.";
114 //-----------------------------------------------------------------------------
115 int RS_SETTINGS::ParseSettings(const MODULE_SETTINGS & s)
119 vector<PARAM_VALUE>::const_iterator pvi;
121 ///////////////////////////
123 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
124 if (pvi == s.moduleParams.end())
126 errorStr = "Parameter \'Port\' not found.";
127 printfd(__FILE__, "Parameter 'Port' not found\n");
130 if (ParseIntInRange(pvi->value[0], 2, 65535, &p))
132 errorStr = "Cannot parse parameter \'Port\': " + errorStr;
133 printfd(__FILE__, "Cannot parse parameter 'Port'\n");
137 ///////////////////////////
138 pv.param = "SendPeriod";
139 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
140 if (pvi == s.moduleParams.end())
142 errorStr = "Parameter \'SendPeriod\' not found.";
143 printfd(__FILE__, "Parameter 'SendPeriod' not found\n");
147 if (ParseIntInRange(pvi->value[0], 5, 600, &sendPeriod))
149 errorStr = "Cannot parse parameter \'SendPeriod\': " + errorStr;
150 printfd(__FILE__, "Cannot parse parameter 'SendPeriod'\n");
153 ///////////////////////////
154 pv.param = "UserParams";
155 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
156 if (pvi == s.moduleParams.end())
158 errorStr = "Parameter \'UserParams\' not found.";
159 printfd(__FILE__, "Parameter 'UserParams' not found\n");
162 userParams = pvi->value;
163 ///////////////////////////
164 pv.param = "Password";
165 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
166 if (pvi == s.moduleParams.end())
168 errorStr = "Parameter \'Password\' not found.";
169 printfd(__FILE__, "Parameter 'Password' not found\n");
172 password = pvi->value[0];
173 ///////////////////////////
174 pv.param = "SubnetFile";
175 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
176 if (pvi == s.moduleParams.end())
178 errorStr = "Parameter \'SubnetFile\' not found.";
179 printfd(__FILE__, "Parameter 'SubnetFile' not found\n");
182 subnetFile = pvi->value[0];
184 NRMapParser nrMapParser;
186 if (nrMapParser.ReadFile(subnetFile))
188 errorStr = nrMapParser.GetErrorStr();
192 netRouters = nrMapParser.GetMap();
194 if (netRouters.empty())
196 errorStr = "Parameter(s) \'Subnet*\' not found.";
197 printfd(__FILE__, "Parameter(s) 'Subnet*' not found\n");
203 //-----------------------------------------------------------------------------
204 //-----------------------------------------------------------------------------
205 //-----------------------------------------------------------------------------
206 REMOTE_SCRIPT::REMOTE_SCRIPT()
214 pthread_mutex_init(&mutex, NULL);
216 //-----------------------------------------------------------------------------
217 REMOTE_SCRIPT::~REMOTE_SCRIPT()
219 pthread_mutex_destroy(&mutex);
221 //-----------------------------------------------------------------------------
222 void * REMOTE_SCRIPT::Run(void * d)
224 REMOTE_SCRIPT * rs = static_cast<REMOTE_SCRIPT *>(d);
226 rs->isRunning = true;
234 rs->isRunning = false;
237 //-----------------------------------------------------------------------------
238 int REMOTE_SCRIPT::ParseSettings()
240 int ret = rsSettings.ParseSettings(settings);
242 errorStr = rsSettings.GetStrError();
244 sendPeriod = rsSettings.GetSendPeriod();
245 halfPeriod = sendPeriod / 2;
249 //-----------------------------------------------------------------------------
250 int REMOTE_SCRIPT::Start()
252 netRouters = rsSettings.GetSubnetsMap();
254 InitEncrypt(&ctx, rsSettings.GetPassword());
256 onAddUserNotifier.SetRemoteScript(this);
257 onDelUserNotifier.SetRemoteScript(this);
259 users->AddNotifierUserAdd(&onAddUserNotifier);
260 users->AddNotifierUserDel(&onDelUserNotifier);
276 if (pthread_create(&thread, NULL, Run, this))
278 errorStr = "Cannot create thread.";
279 printfd(__FILE__, "Cannot create thread\n");
287 //-----------------------------------------------------------------------------
288 int REMOTE_SCRIPT::Stop()
296 authorizedUsers.begin(),
297 authorizedUsers.end(),
298 DisconnectUser(*this)
305 //5 seconds to thread stops itself
306 for (int i = 0; i < 25 && isRunning; i++)
311 //after 5 seconds waiting thread still running. now killing it
314 if (pthread_kill(thread, SIGINT))
316 errorStr = "Cannot kill thread.";
317 printfd(__FILE__, "Cannot kill thread\n");
320 printfd(__FILE__, "REMOTE_SCRIPT killed Run\n");
324 users->DelNotifierUserDel(&onDelUserNotifier);
325 users->DelNotifierUserAdd(&onAddUserNotifier);
329 //-----------------------------------------------------------------------------
330 int REMOTE_SCRIPT::Reload()
332 NRMapParser nrMapParser;
334 if (nrMapParser.ReadFile(rsSettings.GetMapFileName()))
336 errorStr = nrMapParser.GetErrorStr();
341 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
343 printfd(__FILE__, "REMOTE_SCRIPT::Reload()\n");
345 netRouters = nrMapParser.GetMap();
348 std::for_each(authorizedUsers.begin(),
349 authorizedUsers.end(),
350 UpdateRouter(*this));
354 //-----------------------------------------------------------------------------
355 bool REMOTE_SCRIPT::PrepareNet()
357 sock = socket(AF_INET, SOCK_DGRAM, 0);
361 errorStr = "Cannot create socket.";
362 printfd(__FILE__, "Cannot create socket\n");
368 //-----------------------------------------------------------------------------
369 bool REMOTE_SCRIPT::FinalizeNet()
374 //-----------------------------------------------------------------------------
375 void REMOTE_SCRIPT::PeriodicSend()
377 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
379 map<uint32_t, RS_USER>::iterator it(authorizedUsers.begin());
380 while (it != authorizedUsers.end())
382 if (difftime(stgTime, it->second.lastSentTime) - (rand() % halfPeriod) > sendPeriod)
383 //if (stgTime - it->second.lastSentTime > sendPeriod)
385 Send(it->first, it->second);
390 //-----------------------------------------------------------------------------
391 bool REMOTE_SCRIPT::PreparePacket(char * buf, size_t bufSize, uint32_t ip, RS_USER & rsu, bool forceDisconnect) const
393 RS_PACKET_HEADER packetHead;
395 memset(packetHead.padding, 0, sizeof(packetHead.padding));
396 strcpy((char*)packetHead.magic, RS_ID);
397 packetHead.protoVer[0] = '0';
398 packetHead.protoVer[1] = '2';
401 packetHead.packetType = RS_DISCONNECT_PACKET;
405 if (rsu.shortPacketsCount % MAX_SHORT_PCKT == 0)
408 packetHead.packetType = rsu.user->IsInetable() ? RS_CONNECT_PACKET : RS_DISCONNECT_PACKET;
413 packetHead.packetType = rsu.user->IsInetable() ? RS_ALIVE_PACKET : RS_DISCONNECT_PACKET;
416 rsu.shortPacketsCount++;
417 rsu.lastSentTime = stgTime;
419 packetHead.ip = htonl(ip);
420 packetHead.id = htonl(rsu.user->GetID());
421 strncpy((char*)packetHead.login, rsu.user->GetLogin().c_str(), RS_LOGIN_LEN);
422 packetHead.login[RS_LOGIN_LEN - 1] = 0;
424 memcpy(buf, &packetHead, sizeof(packetHead));
426 if (packetHead.packetType == RS_ALIVE_PACKET)
431 RS_PACKET_TAIL packetTail;
433 memset(packetTail.padding, 0, sizeof(packetTail.padding));
434 strcpy((char*)packetTail.magic, RS_ID);
435 vector<string>::const_iterator it;
437 for(it = rsSettings.GetUserParams().begin();
438 it != rsSettings.GetUserParams().end();
441 std::string parameter(GetUserParam(rsu.user, *it));
442 if (params.length() + parameter.length() > RS_PARAMS_LEN - 1)
444 params += parameter + " ";
446 strncpy((char *)packetTail.params, params.c_str(), RS_PARAMS_LEN);
447 packetTail.params[RS_PARAMS_LEN - 1] = 0;
449 assert(sizeof(packetHead) + sizeof(packetTail) <= bufSize && "Insufficient buffer space");
451 Encrypt(&ctx, buf + sizeof(packetHead), (char *)&packetTail, sizeof(packetTail) / 8);
455 //-----------------------------------------------------------------------------
456 bool REMOTE_SCRIPT::Send(uint32_t ip, RS_USER & rsu, bool forceDisconnect) const
458 char buffer[RS_MAX_PACKET_LEN];
460 memset(buffer, 0, sizeof(buffer));
462 if (PreparePacket(buffer, sizeof(buffer), ip, rsu, forceDisconnect))
464 printfd(__FILE__, "REMOTE_SCRIPT::Send() - Invalid packet length!\n");
471 PacketSender(sock, buffer, sizeof(buffer), htons(rsSettings.GetPort()))
476 //-----------------------------------------------------------------------------
477 bool REMOTE_SCRIPT::SendDirect(uint32_t ip, RS_USER & rsu, uint32_t routerIP, bool forceDisconnect) const
479 char buffer[RS_MAX_PACKET_LEN];
481 if (PreparePacket(buffer, sizeof(buffer), ip, rsu, forceDisconnect))
483 printfd(__FILE__, "REMOTE_SCRIPT::SendDirect() - Invalid packet length!\n");
487 struct sockaddr_in sendAddr;
489 sendAddr.sin_family = AF_INET;
490 sendAddr.sin_port = htons(rsSettings.GetPort());
491 sendAddr.sin_addr.s_addr = routerIP;
493 int res = sendto(sock, buffer, sizeof(buffer), 0, (struct sockaddr *)&sendAddr, sizeof(sendAddr));
495 return (res != sizeof(buffer));
497 //-----------------------------------------------------------------------------
498 bool REMOTE_SCRIPT::GetUsers()
502 int h = users->OpenSearch();
505 errorStr = "users->OpenSearch() error.";
506 printfd(__FILE__, "OpenSearch() error\n");
510 while (!users->SearchNext(h, &u))
515 users->CloseSearch(h);
518 //-----------------------------------------------------------------------------
519 void REMOTE_SCRIPT::ChangedIP(user_iter u, uint32_t oldIP, uint32_t newIP)
522 * When ip changes process looks like:
528 RS_USER rsu(IP2Routers(newIP), u);
531 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
532 authorizedUsers[newIP] = rsu;
536 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
537 const map<uint32_t, RS_USER>::iterator it(
538 authorizedUsers.find(oldIP)
540 if (it != authorizedUsers.end())
542 Send(oldIP, it->second, true);
543 authorizedUsers.erase(it);
547 //-----------------------------------------------------------------------------
548 std::vector<uint32_t> REMOTE_SCRIPT::IP2Routers(uint32_t ip)
550 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
551 for (size_t i = 0; i < netRouters.size(); ++i)
553 if ((ip & netRouters[i].subnetMask) == (netRouters[i].subnetIP & netRouters[i].subnetMask))
555 return netRouters[i].routers;
558 return std::vector<uint32_t>();
560 //-----------------------------------------------------------------------------
561 string REMOTE_SCRIPT::GetUserParam(user_iter u, const string & paramName) const
564 if (strcasecmp(paramName.c_str(), "cash") == 0)
565 strprintf(&value, "%f", u->property.cash.Get());
567 if (strcasecmp(paramName.c_str(), "freeMb") == 0)
568 strprintf(&value, "%f", u->property.freeMb.Get());
570 if (strcasecmp(paramName.c_str(), "passive") == 0)
571 strprintf(&value, "%d", u->property.passive.Get());
573 if (strcasecmp(paramName.c_str(), "disabled") == 0)
574 strprintf(&value, "%d", u->property.disabled.Get());
576 if (strcasecmp(paramName.c_str(), "alwaysOnline") == 0)
577 strprintf(&value, "%d", u->property.alwaysOnline.Get());
579 if (strcasecmp(paramName.c_str(), "tariffName") == 0 ||
580 strcasecmp(paramName.c_str(), "tariff") == 0)
581 value = "\"" + u->property.tariffName.Get() + "\"";
583 if (strcasecmp(paramName.c_str(), "nextTariff") == 0)
584 value = "\"" + u->property.nextTariff.Get() + "\"";
586 if (strcasecmp(paramName.c_str(), "address") == 0)
587 value = "\"" + u->property.address.Get() + "\"";
589 if (strcasecmp(paramName.c_str(), "note") == 0)
590 value = "\"" + u->property.note.Get() + "\"";
592 if (strcasecmp(paramName.c_str(), "group") == 0)
593 value = "\"" + u->property.group.Get() + "\"";
595 if (strcasecmp(paramName.c_str(), "email") == 0)
596 value = "\"" + u->property.email.Get() + "\"";
598 if (strcasecmp(paramName.c_str(), "realName") == 0)
599 value = "\"" + u->property.realName.Get() + "\"";
601 if (strcasecmp(paramName.c_str(), "credit") == 0)
602 strprintf(&value, "%f", u->property.credit.Get());
604 if (strcasecmp(paramName.c_str(), "userdata0") == 0)
605 value = "\"" + u->property.userdata0.Get() + "\"";
607 if (strcasecmp(paramName.c_str(), "userdata1") == 0)
608 value = "\"" + u->property.userdata1.Get() + "\"";
610 if (strcasecmp(paramName.c_str(), "userdata2") == 0)
611 value = "\"" + u->property.userdata2.Get() + "\"";
613 if (strcasecmp(paramName.c_str(), "userdata3") == 0)
614 value = "\"" + u->property.userdata3.Get() + "\"";
616 if (strcasecmp(paramName.c_str(), "userdata4") == 0)
617 value = "\"" + u->property.userdata4.Get() + "\"";
619 if (strcasecmp(paramName.c_str(), "userdata5") == 0)
620 value = "\"" + u->property.userdata5.Get() + "\"";
622 if (strcasecmp(paramName.c_str(), "userdata6") == 0)
623 value = "\"" + u->property.userdata6.Get() + "\"";
625 if (strcasecmp(paramName.c_str(), "userdata7") == 0)
626 value = "\"" + u->property.userdata7.Get() + "\"";
628 if (strcasecmp(paramName.c_str(), "userdata8") == 0)
629 value = "\"" + u->property.userdata8.Get() + "\"";
631 if (strcasecmp(paramName.c_str(), "userdata9") == 0)
632 value = "\"" + u->property.userdata9.Get() + "\"";
634 if (strcasecmp(paramName.c_str(), "enabledDirs") == 0)
635 value = u->GetEnabledDirs();
637 printfd(__FILE__, "Unknown value name: %s\n", paramName.c_str());
640 //-----------------------------------------------------------------------------
641 void REMOTE_SCRIPT::SetUserNotifier(user_iter u)
643 RS_CHG_AFTER_NOTIFIER<uint32_t> AfterChgIPNotifier;
645 AfterChgIPNotifier.SetRemoteScript(this);
646 AfterChgIPNotifier.SetUser(u);
647 AfterChgIPNotifierList.push_front(AfterChgIPNotifier);
649 u->AddCurrIPAfterNotifier(&(*AfterChgIPNotifierList.begin()));
651 //-----------------------------------------------------------------------------
652 void REMOTE_SCRIPT::UnSetUserNotifier(user_iter u)
654 list<RS_CHG_AFTER_NOTIFIER<uint32_t> >::iterator ipAIter;
655 std::list<list<RS_CHG_AFTER_NOTIFIER<uint32_t> >::iterator> toErase;
657 for (ipAIter = AfterChgIPNotifierList.begin(); ipAIter != AfterChgIPNotifierList.end(); ++ipAIter)
659 if (ipAIter->GetUser() == u)
661 u->DelCurrIPAfterNotifier(&(*ipAIter));
662 toErase.push_back(ipAIter);
666 std::list<list<RS_CHG_AFTER_NOTIFIER<uint32_t> >::iterator>::iterator eIter;
668 for (eIter = toErase.begin(); eIter != toErase.end(); ++eIter)
670 AfterChgIPNotifierList.erase(*eIter);
673 //-----------------------------------------------------------------------------
674 template <typename varParamType>
675 void RS_CHG_AFTER_NOTIFIER<varParamType>::Notify(const varParamType & oldValue, const varParamType & newValue)
677 rs->ChangedIP(user, oldValue, newValue);
679 //-----------------------------------------------------------------------------
680 void REMOTE_SCRIPT::InitEncrypt(BLOWFISH_CTX * ctx, const string & password) const
682 unsigned char keyL[PASSWD_LEN]; // Пароль для шифровки
683 memset(keyL, 0, PASSWD_LEN);
684 strncpy((char *)keyL, password.c_str(), PASSWD_LEN);
685 Blowfish_Init(ctx, keyL, PASSWD_LEN);
687 //-----------------------------------------------------------------------------
688 void REMOTE_SCRIPT::Encrypt(BLOWFISH_CTX * ctx, char * dst, const char * src, size_t len8) const
691 memcpy(dst, src, len8 * 8);
692 for (size_t i = 0; i < len8; ++i)
693 Blowfish_Encrypt(ctx, (uint32_t *)(dst + i * 8), (uint32_t *)(dst + i * 8 + 4));
695 //-----------------------------------------------------------------------------