X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/44378b3654976b893daa96f44cea9fcb62092209..0907aa4037b12b6b88ee24495d4577a064d4f8db:/projects/stargazer/plugins/other/smux/smux.cpp diff --git a/projects/stargazer/plugins/other/smux/smux.cpp b/projects/stargazer/plugins/other/smux/smux.cpp index fc45fe04..c74aeae9 100644 --- a/projects/stargazer/plugins/other/smux/smux.cpp +++ b/projects/stargazer/plugins/other/smux/smux.cpp @@ -15,17 +15,12 @@ #include #include "stg/common.h" -#include "stg/plugin_creator.h" #include "smux.h" #include "utils.h" -PLUGIN_CREATOR smc; - -PLUGIN * GetPlugin() +namespace { -return smc.GetPlugin(); -} bool SPrefixLess(const Sensors::value_type & a, const Sensors::value_type & b) @@ -33,20 +28,30 @@ bool SPrefixLess(const Sensors::value_type & a, return a.first.PrefixLess(b.first); } +} + +extern "C" STG::Plugin* GetPlugin() +{ + static SMUX plugin; + return &plugin; +} + SMUX_SETTINGS::SMUX_SETTINGS() - : ip(0), - port(0) + : errorStr(), + ip(0), + port(0), + password() {} -int SMUX_SETTINGS::ParseSettings(const MODULE_SETTINGS & s) +int SMUX_SETTINGS::ParseSettings(const STG::ModuleSettings & s) { -PARAM_VALUE pv; -std::vector::const_iterator pvi; +STG::ParamValue pv; +std::vector::const_iterator pvi; int p; pv.param = "Port"; pvi = std::find(s.moduleParams.begin(), s.moduleParams.end(), pv); -if (pvi == s.moduleParams.end()) +if (pvi == s.moduleParams.end() || pvi->value.empty()) { errorStr = "Parameter \'Port\' not found."; printfd(__FILE__, "Parameter 'Port' not found\n"); @@ -58,11 +63,11 @@ if (ParseIntInRange(pvi->value[0], 2, 65535, &p)) printfd(__FILE__, "Cannot parse parameter 'Port'\n"); return -1; } -port = p; +port = static_cast(p); pv.param = "Password"; pvi = std::find(s.moduleParams.begin(), s.moduleParams.end(), pv); -if (pvi == s.moduleParams.end()) +if (pvi == s.moduleParams.end() || pvi->value.empty()) { errorStr = "Parameter \'Password\' not found."; printfd(__FILE__, "Parameter 'Password' not found\n"); @@ -75,7 +80,7 @@ else pv.param = "Server"; pvi = std::find(s.moduleParams.begin(), s.moduleParams.end(), pv); -if (pvi == s.moduleParams.end()) +if (pvi == s.moduleParams.end() || pvi->value.empty()) { errorStr = "Parameter \'Server\' not found."; printfd(__FILE__, "Parameter 'Server' not found\n"); @@ -87,8 +92,7 @@ return 0; } SMUX::SMUX() - : PLUGIN(), - users(NULL), + : users(NULL), tariffs(NULL), admins(NULL), services(NULL), @@ -96,15 +100,14 @@ SMUX::SMUX() traffcounter(NULL), running(false), stopped(true), + needReconnect(false), + lastReconnectTry(0), + reconnectTimeout(1), sock(-1), - smuxHandlers(), - pdusHandlers(), - sensors(), - tables(), - notifiers(), addUserNotifier(*this), delUserNotifier(*this), - addDelTariffNotifier(*this) + addDelTariffNotifier(*this), + logger(STG::PluginLogger::get("smux")) { pthread_mutex_init(&mutex, NULL); @@ -149,7 +152,7 @@ assert(corporations != NULL && "corporations must not be NULL"); assert(traffcounter != NULL && "traffcounter must not be NULL"); if (PrepareNet()) - return -1; + needReconnect = true; // Users sensors[OID(".1.3.6.1.4.1.38313.1.1.1")] = new TotalUsersSensor(*users); @@ -163,6 +166,7 @@ sensors[OID(".1.3.6.1.4.1.38313.1.1.8")] = new PassiveUsersSensor(*users); sensors[OID(".1.3.6.1.4.1.38313.1.1.9")] = new CreditUsersSensor(*users); sensors[OID(".1.3.6.1.4.1.38313.1.1.10")] = new FreeMbUsersSensor(*users); sensors[OID(".1.3.6.1.4.1.38313.1.1.11")] = new TariffChangeUsersSensor(*users); +sensors[OID(".1.3.6.1.4.1.38313.1.1.12")] = new ActiveUsersSensor(*users); // Tariffs sensors[OID(".1.3.6.1.4.1.38313.1.2.1")] = new TotalTariffsSensor(*tariffs); // Admins @@ -196,6 +200,7 @@ if (!running) if (pthread_create(&thread, NULL, Runner, this)) { errorStr = "Cannot create thread."; + logger("Cannot create thread."); printfd(__FILE__, "Cannot create thread\n"); return -1; } @@ -209,8 +214,6 @@ int SMUX::Stop() printfd(__FILE__, "SMUX::Stop() - Before\n"); running = false; -ResetNotifiers(); - if (!stopped) { //5 seconds to thread stops itself @@ -219,31 +222,59 @@ if (!stopped) struct timespec ts = {0, 200000000}; nanosleep(&ts, NULL); } + } - //after 5 seconds waiting thread still running. now killing it - if (!stopped) - { - printfd(__FILE__, "SMUX::Stop() - failed to stop thread, killing it\n"); - if (pthread_kill(thread, SIGINT)) - { - errorStr = "Cannot kill thread."; - printfd(__FILE__, "SMUX::Stop() - Cannot kill thread\n"); - return -1; - } - printfd(__FILE__, "SMUX::Stop() - killed Run\n"); - } +if (stopped) + pthread_join(thread, NULL); + +ResetNotifiers(); + + { + Tables::iterator it; + for (it = tables.begin(); it != tables.end(); ++it) + delete it->second; + } + { + Sensors::iterator it; + for (it = sensors.begin(); it != sensors.end(); ++it) + delete it->second; } -pthread_join(thread, NULL); +tables.erase(tables.begin(), tables.end()); +sensors.erase(sensors.begin(), sensors.end()); close(sock); +if (!stopped) + { + running = true; + return -1; + } + printfd(__FILE__, "SMUX::Stop() - After\n"); return 0; } +int SMUX::Reload(const STG::ModuleSettings & /*ms*/) +{ +if (Stop()) + return -1; +if (Start()) + return -1; +if (!needReconnect) + { + printfd(__FILE__, "SMUX reconnected succesfully.\n"); + logger("Reconnected successfully."); + } +return 0; +} + void * SMUX::Runner(void * d) { +sigset_t signalSet; +sigfillset(&signalSet); +pthread_sigmask(SIG_BLOCK, &signalSet, NULL); + SMUX * smux = static_cast(d); smux->Run(); @@ -253,14 +284,17 @@ return NULL; void SMUX::Run() { -SendOpenPDU(sock); -SendRReqPDU(sock); +stopped = true; +if (!SendOpenPDU(sock)) + needReconnect = true; +if (!SendRReqPDU(sock)) + needReconnect = true; running = true; stopped = false; while(running) { - if (WaitPackets(sock)) + if (WaitPackets(sock) && !needReconnect) { SMUX_PDUs_t * pdus = RecvSMUXPDUs(sock); if (pdus) @@ -268,7 +302,11 @@ while(running) DispatchPDUs(pdus); ASN_STRUCT_FREE(asn_DEF_SMUX_PDUs, pdus); } + else if (running) + Reconnect(); } + else if (running && needReconnect) + Reconnect(); if (!running) break; } @@ -283,6 +321,7 @@ sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { errorStr = "Cannot create socket."; + logger("Cannot create a socket: %s", strerror(errno)); printfd(__FILE__, "Cannot create socket\n"); return true; } @@ -296,6 +335,7 @@ addr.sin_addr.s_addr = smuxSettings.GetIP(); if (connect(sock, reinterpret_cast(&addr), sizeof(addr))) { errorStr = "Cannot connect."; + logger("Cannot connect the socket: %s", strerror(errno)); printfd(__FILE__, "Cannot connect. Message: '%s'\n", strerror(errno)); return true; } @@ -303,17 +343,43 @@ if (connect(sock, reinterpret_cast(&addr), sizeof(addr))) return false; } +bool SMUX::Reconnect() +{ +if (needReconnect && difftime(time(NULL), lastReconnectTry) < reconnectTimeout) + return true; + +time(&lastReconnectTry); +SendClosePDU(sock); +close(sock); +if (!PrepareNet()) + if (SendOpenPDU(sock)) + if (SendRReqPDU(sock)) + { + reconnectTimeout = 1; + needReconnect = false; + logger("Connected successfully"); + printfd(__FILE__, "Connected successfully\n"); + return false; + } + +if (needReconnect) + if (reconnectTimeout < 60) + reconnectTimeout *= 2; + +needReconnect = true; +return true; +} + bool SMUX::DispatchPDUs(const SMUX_PDUs_t * pdus) { -SMUXHandlers::iterator it; -it = smuxHandlers.find(pdus->present); +SMUXHandlers::iterator it(smuxHandlers.find(pdus->present)); if (it != smuxHandlers.end()) { return (this->*(it->second))(pdus); } +#ifdef SMUX_DEBUG else { -#ifdef SMUX_DEBUG switch (pdus->present) { case SMUX_PDUs_PR_NOTHING: @@ -329,8 +395,8 @@ else printfd(__FILE__, "PDUs: undefined\n"); } asn_fprint(stderr, &asn_DEF_SMUX_PDUs, pdus); -#endif } +#endif return false; } @@ -389,20 +455,20 @@ sensors.insert(newSensors.begin(), newSensors.end()); return true; } -void SMUX::SetNotifier(USER_PTR userPtr) +void SMUX::SetNotifier(UserPtr userPtr) { notifiers.push_back(CHG_AFTER_NOTIFIER(*this, userPtr)); -userPtr->GetProperty().tariffName.AddAfterNotifier(¬ifiers.back()); +userPtr->GetProperties().tariffName.AddAfterNotifier(¬ifiers.back()); } -void SMUX::UnsetNotifier(USER_PTR userPtr) +void SMUX::UnsetNotifier(UserPtr userPtr) { std::list::iterator it = notifiers.begin(); while (it != notifiers.end()) { if (it->GetUserPtr() == userPtr) { - userPtr->GetProperty().tariffName.DelAfterNotifier(&(*it)); + userPtr->GetProperties().tariffName.DelAfterNotifier(&(*it)); notifiers.erase(it); break; } @@ -415,7 +481,7 @@ void SMUX::SetNotifiers() int h = users->OpenSearch(); assert(h && "USERS::OpenSearch is always correct"); -USER_PTR u; +UserPtr u; while (!users->SearchNext(h, &u)) SetNotifier(u); @@ -436,15 +502,11 @@ tariffs->DelNotifierAdd(&addDelTariffNotifier); users->DelNotifierUserDel(&delUserNotifier); users->DelNotifierUserAdd(&addUserNotifier); -std::list::iterator it = notifiers.begin(); +std::list::iterator it(notifiers.begin()); while (it != notifiers.end()) { - it->GetUserPtr()->GetProperty().tariffName.DelAfterNotifier(&(*it)); + it->GetUserPtr()->GetProperties().tariffName.DelAfterNotifier(&(*it)); ++it; } -} - -void CHG_AFTER_NOTIFIER::Notify(const std::string &, const std::string &) -{ -smux.UpdateTables(); +notifiers.clear(); }