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"
26 #include "stg/common.h"
27 #include "stg/locker.h"
28 #include "stg/users.h"
29 #include "stg/user_property.h"
30 #include "stg/logger.h"
41 #include <netinet/ip.h>
44 #define MAX_SHORT_PCKT (3)
46 extern volatile time_t stgTime;
48 using RS::REMOTE_SCRIPT;
55 explicit USER_IS(RS::UserPtr u) : user(u) {}
56 bool operator()(const T & notifier) { return notifier.GetUser() == user; }
61 } // namespace anonymous
63 extern "C" STG::Plugin* GetPlugin()
65 static REMOTE_SCRIPT plugin;
68 //-----------------------------------------------------------------------------
69 //-----------------------------------------------------------------------------
70 //-----------------------------------------------------------------------------
71 RS::SETTINGS::SETTINGS()
76 //-----------------------------------------------------------------------------
77 int RS::SETTINGS::ParseSettings(const STG::ModuleSettings & s)
81 std::vector<STG::ParamValue>::const_iterator pvi;
83 ///////////////////////////
85 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
86 if (pvi == s.moduleParams.end() || pvi->value.empty())
88 errorStr = "Parameter \'Port\' not found.";
89 printfd(__FILE__, "Parameter 'Port' not found\n");
92 if (ParseIntInRange(pvi->value[0], 2, 65535, &p))
94 errorStr = "Cannot parse parameter \'Port\': " + errorStr;
95 printfd(__FILE__, "Cannot parse parameter 'Port'\n");
98 port = static_cast<uint16_t>(p);
99 ///////////////////////////
100 pv.param = "SendPeriod";
101 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
102 if (pvi == s.moduleParams.end() || pvi->value.empty())
104 errorStr = "Parameter \'SendPeriod\' not found.";
105 printfd(__FILE__, "Parameter 'SendPeriod' not found\n");
109 if (ParseIntInRange(pvi->value[0], 5, 600, &sendPeriod))
111 errorStr = "Cannot parse parameter \'SendPeriod\': " + errorStr;
112 printfd(__FILE__, "Cannot parse parameter 'SendPeriod'\n");
115 ///////////////////////////
116 pv.param = "UserParams";
117 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
118 if (pvi == s.moduleParams.end() || pvi->value.empty())
120 errorStr = "Parameter \'UserParams\' not found.";
121 printfd(__FILE__, "Parameter 'UserParams' not found\n");
124 userParams = pvi->value;
125 ///////////////////////////
126 pv.param = "Password";
127 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
128 if (pvi == s.moduleParams.end() || pvi->value.empty())
130 errorStr = "Parameter \'Password\' not found.";
131 printfd(__FILE__, "Parameter 'Password' not found\n");
134 password = pvi->value[0];
135 ///////////////////////////
136 pv.param = "SubnetFile";
137 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
138 if (pvi == s.moduleParams.end() || pvi->value.empty())
140 errorStr = "Parameter \'SubnetFile\' not found.";
141 printfd(__FILE__, "Parameter 'SubnetFile' not found\n");
144 subnetFile = pvi->value[0];
146 NRMapParser nrMapParser;
148 if (!nrMapParser.ReadFile(subnetFile))
150 netRouters = nrMapParser.GetMap();
154 STG::PluginLogger::get("rscript")("mod_rscript: error opening subnets file '%s'", subnetFile.c_str());
159 //-----------------------------------------------------------------------------
160 //-----------------------------------------------------------------------------
161 //-----------------------------------------------------------------------------
162 REMOTE_SCRIPT::REMOTE_SCRIPT()
168 onAddUserNotifier(*this),
169 onDelUserNotifier(*this),
170 logger(STG::PluginLogger::get("rscript"))
173 //-----------------------------------------------------------------------------
174 REMOTE_SCRIPT::~REMOTE_SCRIPT()
177 //-----------------------------------------------------------------------------
178 void REMOTE_SCRIPT::Run(std::stop_token token)
181 sigfillset(&signalSet);
182 pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
186 while (!token.stop_requested())
194 //-----------------------------------------------------------------------------
195 int REMOTE_SCRIPT::ParseSettings()
197 int ret = rsSettings.ParseSettings(settings);
199 errorStr = rsSettings.GetStrError();
201 sendPeriod = rsSettings.GetSendPeriod();
202 halfPeriod = sendPeriod / 2;
206 //-----------------------------------------------------------------------------
207 int REMOTE_SCRIPT::Start()
209 netRouters = rsSettings.GetSubnetsMap();
211 InitEncrypt(rsSettings.GetPassword());
213 users->AddNotifierUserAdd(&onAddUserNotifier);
214 users->AddNotifierUserDel(&onDelUserNotifier);
228 m_thread = std::jthread([this](auto token){ Run(token); });
234 //-----------------------------------------------------------------------------
235 int REMOTE_SCRIPT::Stop()
240 m_thread.request_stop();
243 authorizedUsers.begin(),
244 authorizedUsers.end(),
245 DisconnectUser(*this)
252 //5 seconds to thread stops itself
253 for (int i = 0; i < 25 && isRunning; i++)
255 struct timespec ts = {0, 200000000};
256 nanosleep(&ts, NULL);
260 users->DelNotifierUserDel(&onDelUserNotifier);
261 users->DelNotifierUserAdd(&onAddUserNotifier);
265 logger("Cannot stop thread.");
271 //-----------------------------------------------------------------------------
272 int REMOTE_SCRIPT::Reload(const STG::ModuleSettings & /*ms*/)
274 NRMapParser nrMapParser;
276 if (nrMapParser.ReadFile(rsSettings.GetMapFileName()))
278 errorStr = nrMapParser.GetErrorStr();
279 logger("Map file reading error: %s", errorStr.c_str());
284 std::lock_guard lock(m_mutex);
286 printfd(__FILE__, "REMOTE_SCRIPT::Reload()\n");
288 netRouters = nrMapParser.GetMap();
291 std::for_each(authorizedUsers.begin(),
292 authorizedUsers.end(),
293 UpdateRouter(*this));
295 logger("%s reloaded successfully.", rsSettings.GetMapFileName().c_str());
296 printfd(__FILE__, "REMOTE_SCRIPT::Reload() %s reloaded successfully.\n");
300 //-----------------------------------------------------------------------------
301 bool REMOTE_SCRIPT::PrepareNet()
303 sock = socket(AF_INET, SOCK_DGRAM, 0);
307 errorStr = "Cannot create socket.";
308 logger("Canot create a socket: %s", strerror(errno));
309 printfd(__FILE__, "Cannot create socket\n");
315 //-----------------------------------------------------------------------------
316 bool REMOTE_SCRIPT::FinalizeNet()
321 //-----------------------------------------------------------------------------
322 void REMOTE_SCRIPT::PeriodicSend()
324 std::lock_guard lock(m_mutex);
326 std::map<uint32_t, RS::USER>::iterator it(authorizedUsers.begin());
327 while (it != authorizedUsers.end())
329 if (difftime(stgTime, it->second.lastSentTime) - (rand() % halfPeriod) > sendPeriod)
336 //-----------------------------------------------------------------------------
338 bool REMOTE_SCRIPT::PreparePacket(char * buf, size_t, RS::USER & rsu, bool forceDisconnect) const
340 bool REMOTE_SCRIPT::PreparePacket(char * buf, size_t bufSize, RS::USER & rsu, bool forceDisconnect) const
343 RS::PACKET_HEADER packetHead;
345 memset(packetHead.padding, 0, sizeof(packetHead.padding));
346 memcpy(packetHead.magic, RS_ID, sizeof(RS_ID));
347 packetHead.protoVer[0] = '0';
348 packetHead.protoVer[1] = '2';
351 packetHead.packetType = RS_DISCONNECT_PACKET;
352 printfd(__FILE__, "RSCRIPT: force disconnect for '%s'\n", rsu.user->GetLogin().c_str());
356 if (rsu.shortPacketsCount % MAX_SHORT_PCKT == 0)
359 packetHead.packetType = rsu.user->IsInetable() ? RS_CONNECT_PACKET : RS_DISCONNECT_PACKET;
360 if (rsu.user->IsInetable())
361 printfd(__FILE__, "RSCRIPT: connect for '%s'\n", rsu.user->GetLogin().c_str());
363 printfd(__FILE__, "RSCRIPT: disconnect for '%s'\n", rsu.user->GetLogin().c_str());
368 packetHead.packetType = rsu.user->IsInetable() ? RS_ALIVE_PACKET : RS_DISCONNECT_PACKET;
369 if (rsu.user->IsInetable())
370 printfd(__FILE__, "RSCRIPT: alive for '%s'\n", rsu.user->GetLogin().c_str());
372 printfd(__FILE__, "RSCRIPT: disconnect for '%s'\n", rsu.user->GetLogin().c_str());
375 rsu.shortPacketsCount++;
376 rsu.lastSentTime = stgTime;
378 packetHead.ip = htonl(rsu.ip);
379 packetHead.id = htonl(rsu.user->GetID());
380 strncpy(reinterpret_cast<char*>(packetHead.login), rsu.user->GetLogin().c_str(), RS_LOGIN_LEN);
381 packetHead.login[RS_LOGIN_LEN - 1] = 0;
383 memcpy(buf, &packetHead, sizeof(packetHead));
385 if (packetHead.packetType == RS_ALIVE_PACKET)
390 RS::PACKET_TAIL packetTail;
392 memset(packetTail.padding, 0, sizeof(packetTail.padding));
393 memcpy(packetTail.magic, RS_ID, sizeof(RS_ID));
394 std::vector<std::string>::const_iterator it;
396 for(it = rsSettings.GetUserParams().begin();
397 it != rsSettings.GetUserParams().end();
400 std::string parameter(rsu.user->GetParamValue(it->c_str()));
401 if (params.length() + parameter.length() > RS_PARAMS_LEN - 1)
403 logger("Script params string length %d exceeds the limit of %d symbols.", params.length() + parameter.length(), RS_PARAMS_LEN);
406 params += parameter + " ";
408 strncpy(reinterpret_cast<char*>(packetTail.params), params.c_str(), RS_PARAMS_LEN);
409 packetTail.params[RS_PARAMS_LEN - 1] = 0;
411 assert(sizeof(packetHead) + sizeof(packetTail) <= bufSize && "Insufficient buffer space");
413 Encrypt(buf + sizeof(packetHead), reinterpret_cast<char *>(&packetTail), sizeof(packetTail) / 8);
417 //-----------------------------------------------------------------------------
418 bool REMOTE_SCRIPT::Send(RS::USER & rsu, bool forceDisconnect) const
420 char buffer[RS_MAX_PACKET_LEN];
422 memset(buffer, 0, sizeof(buffer));
424 if (PreparePacket(buffer, sizeof(buffer), rsu, forceDisconnect))
426 printfd(__FILE__, "REMOTE_SCRIPT::Send() - Invalid packet length!\n");
430 for (const auto& ip : rsu.routers)
432 struct sockaddr_in sendAddr;
434 sendAddr.sin_family = AF_INET;
435 sendAddr.sin_port = htons(rsSettings.GetPort());
436 sendAddr.sin_addr.s_addr = ip;
438 return sendto(sock, buffer, sizeof(buffer), 0, reinterpret_cast<struct sockaddr*>(&sendAddr), sizeof(sendAddr));
443 //-----------------------------------------------------------------------------
444 bool REMOTE_SCRIPT::SendDirect(RS::USER & rsu, uint32_t routerIP, bool forceDisconnect) const
446 char buffer[RS_MAX_PACKET_LEN];
448 if (PreparePacket(buffer, sizeof(buffer), rsu, forceDisconnect))
450 printfd(__FILE__, "REMOTE_SCRIPT::SendDirect() - Invalid packet length!\n");
454 struct sockaddr_in sendAddr;
456 sendAddr.sin_family = AF_INET;
457 sendAddr.sin_port = htons(rsSettings.GetPort());
458 sendAddr.sin_addr.s_addr = routerIP;
460 ssize_t res = sendto(sock, buffer, sizeof(buffer), 0, reinterpret_cast<struct sockaddr *>(&sendAddr), sizeof(sendAddr));
463 logger("sendto error: %s", strerror(errno));
465 return (res != sizeof(buffer));
467 //-----------------------------------------------------------------------------
468 bool REMOTE_SCRIPT::GetUsers()
472 int h = users->OpenSearch();
473 assert(h && "USERS::OpenSearch is always correct");
475 while (!users->SearchNext(h, &u))
480 users->CloseSearch(h);
483 //-----------------------------------------------------------------------------
484 std::vector<uint32_t> REMOTE_SCRIPT::IP2Routers(uint32_t ip)
486 std::lock_guard lock(m_mutex);
487 for (size_t i = 0; i < netRouters.size(); ++i)
489 if ((ip & netRouters[i].subnetMask) == (netRouters[i].subnetIP & netRouters[i].subnetMask))
491 return netRouters[i].routers;
494 return std::vector<uint32_t>();
496 //-----------------------------------------------------------------------------
497 void REMOTE_SCRIPT::SetUserNotifiers(UserPtr u)
499 ipNotifierList.push_front(RS::IP_NOTIFIER(*this, u));
500 connNotifierList.push_front(RS::CONNECTED_NOTIFIER(*this, u));
502 //-----------------------------------------------------------------------------
503 void REMOTE_SCRIPT::UnSetUserNotifiers(UserPtr u)
505 ipNotifierList.erase(std::remove_if(ipNotifierList.begin(),
506 ipNotifierList.end(),
507 USER_IS<IP_NOTIFIER>(u)),
508 ipNotifierList.end());
509 connNotifierList.erase(std::remove_if(connNotifierList.begin(),
510 connNotifierList.end(),
511 USER_IS<CONNECTED_NOTIFIER>(u)),
512 connNotifierList.end());
515 //-----------------------------------------------------------------------------
516 void REMOTE_SCRIPT::AddRSU(UserPtr user)
518 RS::USER rsu(IP2Routers(user->GetCurrIP()), user);
521 std::lock_guard lock(m_mutex);
522 authorizedUsers.insert(std::make_pair(user->GetCurrIP(), rsu));
524 //-----------------------------------------------------------------------------
525 void REMOTE_SCRIPT::DelRSU(UserPtr user)
527 std::lock_guard lock(m_mutex);
528 std::map<uint32_t, RS::USER>::iterator it(authorizedUsers.begin());
529 while (it != authorizedUsers.end())
531 if (it->second.user == user)
533 Send(it->second, true);
534 authorizedUsers.erase(it);
539 /*const std::map<uint32_t, RS::USER>::iterator it(
540 authorizedUsers.find(user->GetCurrIP())
542 if (it != authorizedUsers.end())
544 Send(it->second, true);
545 authorizedUsers.erase(it);
548 //-----------------------------------------------------------------------------
549 void RS::IP_NOTIFIER::Notify(const uint32_t & /*oldValue*/, const uint32_t & newValue)
556 //-----------------------------------------------------------------------------
557 void RS::CONNECTED_NOTIFIER::Notify(const bool & /*oldValue*/, const bool & newValue)
564 //-----------------------------------------------------------------------------
565 void REMOTE_SCRIPT::InitEncrypt(const std::string & password) const
567 unsigned char keyL[PASSWD_LEN]; // Пароль для шифровки
568 memset(keyL, 0, PASSWD_LEN);
569 strncpy(reinterpret_cast<char*>(keyL), password.c_str(), PASSWD_LEN);
570 Blowfish_Init(&ctx, keyL, PASSWD_LEN);
572 //-----------------------------------------------------------------------------
573 void REMOTE_SCRIPT::Encrypt(void * dst, const void * src, size_t len8) const
576 memcpy(dst, src, len8 * 8);
577 for (size_t i = 0; i < len8; ++i)
578 Blowfish_Encrypt(&ctx, static_cast<uint32_t *>(dst) + i * 2, static_cast<uint32_t *>(dst) + i * 2 + 1);
580 //-----------------------------------------------------------------------------