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 #include "ur_functor.h"
25 #include "send_functor.h"
27 #include "stg/common.h"
28 #include "stg/locker.h"
29 #include "stg/users.h"
30 #include "stg/user_property.h"
31 #include "stg/logger.h"
42 #include <netinet/ip.h>
45 #define MAX_SHORT_PCKT (3)
47 extern volatile time_t stgTime;
49 using RS::REMOTE_SCRIPT;
56 explicit USER_IS(RS::UserPtr u) : user(u) {}
57 bool operator()(const T & notifier) { return notifier.GetUser() == user; }
62 } // namespace anonymous
64 extern "C" STG::Plugin* GetPlugin()
66 static REMOTE_SCRIPT plugin;
69 //-----------------------------------------------------------------------------
70 //-----------------------------------------------------------------------------
71 //-----------------------------------------------------------------------------
72 RS::SETTINGS::SETTINGS()
77 //-----------------------------------------------------------------------------
78 int RS::SETTINGS::ParseSettings(const STG::ModuleSettings & s)
82 std::vector<STG::ParamValue>::const_iterator pvi;
84 ///////////////////////////
86 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
87 if (pvi == s.moduleParams.end() || pvi->value.empty())
89 errorStr = "Parameter \'Port\' not found.";
90 printfd(__FILE__, "Parameter 'Port' not found\n");
93 if (ParseIntInRange(pvi->value[0], 2, 65535, &p))
95 errorStr = "Cannot parse parameter \'Port\': " + errorStr;
96 printfd(__FILE__, "Cannot parse parameter 'Port'\n");
99 port = static_cast<uint16_t>(p);
100 ///////////////////////////
101 pv.param = "SendPeriod";
102 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
103 if (pvi == s.moduleParams.end() || pvi->value.empty())
105 errorStr = "Parameter \'SendPeriod\' not found.";
106 printfd(__FILE__, "Parameter 'SendPeriod' not found\n");
110 if (ParseIntInRange(pvi->value[0], 5, 600, &sendPeriod))
112 errorStr = "Cannot parse parameter \'SendPeriod\': " + errorStr;
113 printfd(__FILE__, "Cannot parse parameter 'SendPeriod'\n");
116 ///////////////////////////
117 pv.param = "UserParams";
118 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
119 if (pvi == s.moduleParams.end() || pvi->value.empty())
121 errorStr = "Parameter \'UserParams\' not found.";
122 printfd(__FILE__, "Parameter 'UserParams' not found\n");
125 userParams = pvi->value;
126 ///////////////////////////
127 pv.param = "Password";
128 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
129 if (pvi == s.moduleParams.end() || pvi->value.empty())
131 errorStr = "Parameter \'Password\' not found.";
132 printfd(__FILE__, "Parameter 'Password' not found\n");
135 password = pvi->value[0];
136 ///////////////////////////
137 pv.param = "SubnetFile";
138 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
139 if (pvi == s.moduleParams.end() || pvi->value.empty())
141 errorStr = "Parameter \'SubnetFile\' not found.";
142 printfd(__FILE__, "Parameter 'SubnetFile' not found\n");
145 subnetFile = pvi->value[0];
147 NRMapParser nrMapParser;
149 if (!nrMapParser.ReadFile(subnetFile))
151 netRouters = nrMapParser.GetMap();
155 STG::PluginLogger::get("rscript")("mod_rscript: error opening subnets file '%s'", subnetFile.c_str());
160 //-----------------------------------------------------------------------------
161 //-----------------------------------------------------------------------------
162 //-----------------------------------------------------------------------------
163 REMOTE_SCRIPT::REMOTE_SCRIPT()
170 onAddUserNotifier(*this),
171 onDelUserNotifier(*this),
172 logger(STG::PluginLogger::get("rscript"))
174 pthread_mutex_init(&mutex, NULL);
176 //-----------------------------------------------------------------------------
177 REMOTE_SCRIPT::~REMOTE_SCRIPT()
179 pthread_mutex_destroy(&mutex);
181 //-----------------------------------------------------------------------------
182 void * REMOTE_SCRIPT::Run(void * d)
185 sigfillset(&signalSet);
186 pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
188 REMOTE_SCRIPT * rs = static_cast<REMOTE_SCRIPT *>(d);
190 rs->isRunning = true;
198 rs->isRunning = false;
201 //-----------------------------------------------------------------------------
202 int REMOTE_SCRIPT::ParseSettings()
204 int ret = rsSettings.ParseSettings(settings);
206 errorStr = rsSettings.GetStrError();
208 sendPeriod = rsSettings.GetSendPeriod();
209 halfPeriod = sendPeriod / 2;
213 //-----------------------------------------------------------------------------
214 int REMOTE_SCRIPT::Start()
216 netRouters = rsSettings.GetSubnetsMap();
218 InitEncrypt(&ctx, rsSettings.GetPassword());
220 users->AddNotifierUserAdd(&onAddUserNotifier);
221 users->AddNotifierUserDel(&onDelUserNotifier);
237 if (pthread_create(&thread, NULL, Run, this))
239 errorStr = "Cannot create thread.";
240 logger("Cannot create thread.");
241 printfd(__FILE__, "Cannot create thread\n");
249 //-----------------------------------------------------------------------------
250 int REMOTE_SCRIPT::Stop()
258 authorizedUsers.begin(),
259 authorizedUsers.end(),
260 DisconnectUser(*this)
267 //5 seconds to thread stops itself
268 for (int i = 0; i < 25 && isRunning; i++)
270 struct timespec ts = {0, 200000000};
271 nanosleep(&ts, NULL);
275 users->DelNotifierUserDel(&onDelUserNotifier);
276 users->DelNotifierUserAdd(&onAddUserNotifier);
280 logger("Cannot stop thread.");
286 //-----------------------------------------------------------------------------
287 int REMOTE_SCRIPT::Reload(const STG::ModuleSettings & /*ms*/)
289 NRMapParser nrMapParser;
291 if (nrMapParser.ReadFile(rsSettings.GetMapFileName()))
293 errorStr = nrMapParser.GetErrorStr();
294 logger("Map file reading error: %s", errorStr.c_str());
299 STG_LOCKER lock(&mutex);
301 printfd(__FILE__, "REMOTE_SCRIPT::Reload()\n");
303 netRouters = nrMapParser.GetMap();
306 std::for_each(authorizedUsers.begin(),
307 authorizedUsers.end(),
308 UpdateRouter(*this));
310 logger("%s reloaded successfully.", rsSettings.GetMapFileName().c_str());
311 printfd(__FILE__, "REMOTE_SCRIPT::Reload() %s reloaded successfully.\n");
315 //-----------------------------------------------------------------------------
316 bool REMOTE_SCRIPT::PrepareNet()
318 sock = socket(AF_INET, SOCK_DGRAM, 0);
322 errorStr = "Cannot create socket.";
323 logger("Canot create a socket: %s", strerror(errno));
324 printfd(__FILE__, "Cannot create socket\n");
330 //-----------------------------------------------------------------------------
331 bool REMOTE_SCRIPT::FinalizeNet()
336 //-----------------------------------------------------------------------------
337 void REMOTE_SCRIPT::PeriodicSend()
339 STG_LOCKER lock(&mutex);
341 std::map<uint32_t, RS::USER>::iterator it(authorizedUsers.begin());
342 while (it != authorizedUsers.end())
344 if (difftime(stgTime, it->second.lastSentTime) - (rand() % halfPeriod) > sendPeriod)
351 //-----------------------------------------------------------------------------
353 bool REMOTE_SCRIPT::PreparePacket(char * buf, size_t, RS::USER & rsu, bool forceDisconnect) const
355 bool REMOTE_SCRIPT::PreparePacket(char * buf, size_t bufSize, RS::USER & rsu, bool forceDisconnect) const
358 RS::PACKET_HEADER packetHead;
360 memset(packetHead.padding, 0, sizeof(packetHead.padding));
361 strcpy((char*)packetHead.magic, RS_ID);
362 packetHead.protoVer[0] = '0';
363 packetHead.protoVer[1] = '2';
366 packetHead.packetType = RS_DISCONNECT_PACKET;
367 printfd(__FILE__, "RSCRIPT: force disconnect for '%s'\n", rsu.user->GetLogin().c_str());
371 if (rsu.shortPacketsCount % MAX_SHORT_PCKT == 0)
374 packetHead.packetType = rsu.user->IsInetable() ? RS_CONNECT_PACKET : RS_DISCONNECT_PACKET;
375 if (rsu.user->IsInetable())
376 printfd(__FILE__, "RSCRIPT: connect for '%s'\n", rsu.user->GetLogin().c_str());
378 printfd(__FILE__, "RSCRIPT: disconnect for '%s'\n", rsu.user->GetLogin().c_str());
383 packetHead.packetType = rsu.user->IsInetable() ? RS_ALIVE_PACKET : RS_DISCONNECT_PACKET;
384 if (rsu.user->IsInetable())
385 printfd(__FILE__, "RSCRIPT: alive for '%s'\n", rsu.user->GetLogin().c_str());
387 printfd(__FILE__, "RSCRIPT: disconnect for '%s'\n", rsu.user->GetLogin().c_str());
390 rsu.shortPacketsCount++;
391 rsu.lastSentTime = stgTime;
393 packetHead.ip = htonl(rsu.ip);
394 packetHead.id = htonl(rsu.user->GetID());
395 strncpy((char*)packetHead.login, rsu.user->GetLogin().c_str(), RS_LOGIN_LEN);
396 packetHead.login[RS_LOGIN_LEN - 1] = 0;
398 memcpy(buf, &packetHead, sizeof(packetHead));
400 if (packetHead.packetType == RS_ALIVE_PACKET)
405 RS::PACKET_TAIL packetTail;
407 memset(packetTail.padding, 0, sizeof(packetTail.padding));
408 strcpy((char*)packetTail.magic, RS_ID);
409 std::vector<std::string>::const_iterator it;
411 for(it = rsSettings.GetUserParams().begin();
412 it != rsSettings.GetUserParams().end();
415 std::string parameter(rsu.user->GetParamValue(it->c_str()));
416 if (params.length() + parameter.length() > RS_PARAMS_LEN - 1)
418 logger("Script params string length %d exceeds the limit of %d symbols.", params.length() + parameter.length(), RS_PARAMS_LEN);
421 params += parameter + " ";
423 strncpy((char *)packetTail.params, params.c_str(), RS_PARAMS_LEN);
424 packetTail.params[RS_PARAMS_LEN - 1] = 0;
426 assert(sizeof(packetHead) + sizeof(packetTail) <= bufSize && "Insufficient buffer space");
428 Encrypt(&ctx, buf + sizeof(packetHead), (char *)&packetTail, sizeof(packetTail) / 8);
432 //-----------------------------------------------------------------------------
433 bool REMOTE_SCRIPT::Send(RS::USER & rsu, bool forceDisconnect) const
435 char buffer[RS_MAX_PACKET_LEN];
437 memset(buffer, 0, sizeof(buffer));
439 if (PreparePacket(buffer, sizeof(buffer), rsu, forceDisconnect))
441 printfd(__FILE__, "REMOTE_SCRIPT::Send() - Invalid packet length!\n");
448 PacketSender(sock, buffer, sizeof(buffer), static_cast<uint16_t>(htons(rsSettings.GetPort())))
453 //-----------------------------------------------------------------------------
454 bool REMOTE_SCRIPT::SendDirect(RS::USER & rsu, uint32_t routerIP, bool forceDisconnect) const
456 char buffer[RS_MAX_PACKET_LEN];
458 if (PreparePacket(buffer, sizeof(buffer), rsu, forceDisconnect))
460 printfd(__FILE__, "REMOTE_SCRIPT::SendDirect() - Invalid packet length!\n");
464 struct sockaddr_in sendAddr;
466 sendAddr.sin_family = AF_INET;
467 sendAddr.sin_port = static_cast<uint16_t>(htons(rsSettings.GetPort()));
468 sendAddr.sin_addr.s_addr = routerIP;
470 ssize_t res = sendto(sock, buffer, sizeof(buffer), 0, (struct sockaddr *)&sendAddr, sizeof(sendAddr));
473 logger("sendto error: %s", strerror(errno));
475 return (res != sizeof(buffer));
477 //-----------------------------------------------------------------------------
478 bool REMOTE_SCRIPT::GetUsers()
482 int h = users->OpenSearch();
483 assert(h && "USERS::OpenSearch is always correct");
485 while (!users->SearchNext(h, &u))
490 users->CloseSearch(h);
493 //-----------------------------------------------------------------------------
494 std::vector<uint32_t> REMOTE_SCRIPT::IP2Routers(uint32_t ip)
496 STG_LOCKER lock(&mutex);
497 for (size_t i = 0; i < netRouters.size(); ++i)
499 if ((ip & netRouters[i].subnetMask) == (netRouters[i].subnetIP & netRouters[i].subnetMask))
501 return netRouters[i].routers;
504 return std::vector<uint32_t>();
506 //-----------------------------------------------------------------------------
507 void REMOTE_SCRIPT::SetUserNotifiers(UserPtr u)
509 ipNotifierList.push_front(RS::IP_NOTIFIER(*this, u));
510 connNotifierList.push_front(RS::CONNECTED_NOTIFIER(*this, u));
512 //-----------------------------------------------------------------------------
513 void REMOTE_SCRIPT::UnSetUserNotifiers(UserPtr u)
515 ipNotifierList.erase(std::remove_if(ipNotifierList.begin(),
516 ipNotifierList.end(),
517 USER_IS<IP_NOTIFIER>(u)),
518 ipNotifierList.end());
519 connNotifierList.erase(std::remove_if(connNotifierList.begin(),
520 connNotifierList.end(),
521 USER_IS<CONNECTED_NOTIFIER>(u)),
522 connNotifierList.end());
525 //-----------------------------------------------------------------------------
526 void REMOTE_SCRIPT::AddRSU(UserPtr user)
528 RS::USER rsu(IP2Routers(user->GetCurrIP()), user);
531 STG_LOCKER lock(&mutex);
532 authorizedUsers.insert(std::make_pair(user->GetCurrIP(), rsu));
534 //-----------------------------------------------------------------------------
535 void REMOTE_SCRIPT::DelRSU(UserPtr user)
537 STG_LOCKER lock(&mutex);
538 std::map<uint32_t, RS::USER>::iterator it(authorizedUsers.begin());
539 while (it != authorizedUsers.end())
541 if (it->second.user == user)
543 Send(it->second, true);
544 authorizedUsers.erase(it);
549 /*const std::map<uint32_t, RS::USER>::iterator it(
550 authorizedUsers.find(user->GetCurrIP())
552 if (it != authorizedUsers.end())
554 Send(it->second, true);
555 authorizedUsers.erase(it);
558 //-----------------------------------------------------------------------------
559 void RS::IP_NOTIFIER::Notify(const uint32_t & /*oldValue*/, const uint32_t & newValue)
566 //-----------------------------------------------------------------------------
567 void RS::CONNECTED_NOTIFIER::Notify(const bool & /*oldValue*/, const bool & newValue)
574 //-----------------------------------------------------------------------------
575 void REMOTE_SCRIPT::InitEncrypt(BLOWFISH_CTX * ctx, const std::string & password) const
577 unsigned char keyL[PASSWD_LEN]; // Пароль для шифровки
578 memset(keyL, 0, PASSWD_LEN);
579 strncpy((char *)keyL, password.c_str(), PASSWD_LEN);
580 Blowfish_Init(ctx, keyL, PASSWD_LEN);
582 //-----------------------------------------------------------------------------
583 void REMOTE_SCRIPT::Encrypt(BLOWFISH_CTX * ctx, void * dst, const void * src, size_t len8) const
586 memcpy(dst, src, len8 * 8);
587 for (size_t i = 0; i < len8; ++i)
588 Blowfish_Encrypt(ctx, static_cast<uint32_t *>(dst) + i * 2, static_cast<uint32_t *>(dst) + i * 2 + 1);
590 //-----------------------------------------------------------------------------