4 #include "stg/user_property.h"
13 using STG::PING_SETTINGS;
18 extern "C" STG::Plugin* GetPlugin()
25 //-----------------------------------------------------------------------------
26 //-----------------------------------------------------------------------------
27 //-----------------------------------------------------------------------------
28 int PING_SETTINGS::ParseSettings(const ModuleSettings & s)
31 std::vector<ParamValue>::const_iterator pvi;
33 pv.param = "PingDelay";
34 pvi = std::find(s.moduleParams.begin(), s.moduleParams.end(), pv);
35 if (pvi == s.moduleParams.end() || pvi->value.empty())
37 errorStr = "Parameter \'PingDelay\' not found.";
38 printfd(__FILE__, "Parameter 'PingDelay' not found\n");
41 if (ParseIntInRange(pvi->value[0], 5, 3600, &pingDelay) != 0)
43 errorStr = "Cannot parse parameter \'PingDelay\': " + errorStr;
44 printfd(__FILE__, "Canot parse parameter 'PingDelay'\n");
50 //-----------------------------------------------------------------------------
54 logger(PluginLogger::get("ping"))
57 //-----------------------------------------------------------------------------
58 int PING::ParseSettings()
60 auto ret = pingSettings.ParseSettings(settings);
62 errorStr = pingSettings.GetStrError();
65 //-----------------------------------------------------------------------------
70 m_onAddUserConn = users->onAdd([this](auto user){ AddUser(user); });
71 m_onDelUserConn = users->onDel([this](auto user){ DelUser(user); });
73 m_pinger.SetDelayTime(pingSettings.GetPingDelay());
76 m_thread = std::jthread([this](auto token){ Run(std::move(token)); });
80 //-----------------------------------------------------------------------------
83 std::lock_guard lock(m_mutex);
85 if (!m_thread.joinable())
89 m_thread.request_stop();
90 //5 seconds to thread stops itself
91 struct timespec ts = {0, 200000000};
92 for (int i = 0; i < 25; i++)
97 nanosleep(&ts, nullptr);
100 m_onAddUserConn.disconnect();
101 m_onDelUserConn.disconnect();
112 //-----------------------------------------------------------------------------
113 bool PING::IsRunning()
117 //-----------------------------------------------------------------------------
118 void PING::Run(std::stop_token token)
121 sigfillset(&signalSet);
122 pthread_sigmask(SIG_BLOCK, &signalSet, nullptr);
126 long delay = (10000000 * pingSettings.GetPingDelay()) / 3 + 50000000;
128 while (!token.stop_requested())
130 auto iter = usersList.begin();
132 std::lock_guard lock(m_mutex);
133 while (iter != usersList.end())
135 if ((*iter)->GetProperties().ips.ConstData().onlyOneIP())
137 uint32_t ip = (*iter)->GetProperties().ips.ConstData()[0].ip;
139 if (m_pinger.GetIPTime(ip, t) == 0)
142 (*iter)->UpdatePingTime(t);
147 uint32_t ip = (*iter)->GetCurrIP();
151 if (m_pinger.GetIPTime(ip, t) == 0)
154 (*iter)->UpdatePingTime(t);
161 struct timespec ts = {delay / 1000000000, delay % 1000000000};
162 for (int i = 0; i < 100; i++)
164 if (!token.stop_requested())
166 nanosleep(&ts, nullptr);
173 //-----------------------------------------------------------------------------
174 void PING::SetUserNotifiers(UserPtr u)
176 m_conns.emplace_back(
178 u->afterCurrIPChange([this](auto oldVal, auto newVal){ updateCurrIP(oldVal, newVal); }),
179 u->GetProperties().ips.afterChange([this](const auto& oldVal, const auto& newVal){ updateIPs(oldVal, newVal); })
182 //-----------------------------------------------------------------------------
183 void PING::UnSetUserNotifiers(UserPtr u)
185 m_conns.erase(std::remove_if(m_conns.begin(), m_conns.end(),
186 [u](const auto& c){ return std::get<0>(c) == u->GetID(); }),
189 //-----------------------------------------------------------------------------
190 void PING::GetUsers()
192 std::lock_guard lock(m_mutex);
195 int h = users->OpenSearch();
196 assert(h && "USERS::OpenSearch is always correct");
198 while (users->SearchNext(h, &u) == 0)
200 usersList.push_back(u);
202 if (u->GetProperties().ips.ConstData().onlyOneIP())
204 m_pinger.AddIP(u->GetProperties().ips.ConstData()[0].ip);
208 uint32_t ip = u->GetCurrIP();
214 users->CloseSearch(h);
216 //-----------------------------------------------------------------------------
217 void PING::AddUser(UserPtr u)
219 std::lock_guard lock(m_mutex);
222 usersList.push_back(u);
224 //-----------------------------------------------------------------------------
225 void PING::DelUser(UserPtr u)
227 std::lock_guard lock(m_mutex);
229 UnSetUserNotifiers(u);
231 std::list<UserPtr>::iterator users_iter;
232 users_iter = usersList.begin();
234 while (users_iter != usersList.end())
236 if (u == *users_iter)
238 usersList.erase(users_iter);
244 //-----------------------------------------------------------------------------
245 void PING::updateCurrIP(uint32_t oldVal, uint32_t newVal)
247 m_pinger.DelIP(oldVal);
249 m_pinger.AddIP(newVal);
251 //-----------------------------------------------------------------------------
252 void PING::updateIPs(const UserIPs& oldVal, const UserIPs& newVal)
254 if (oldVal.onlyOneIP())
255 m_pinger.DelIP(oldVal[0].ip);
257 if (newVal.onlyOneIP())
258 m_pinger.AddIP(newVal[0].ip);