]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/other/rscript/rscript.h
Finalize transition to Boost.UnitTest.
[stg.git] / projects / stargazer / plugins / other / rscript / rscript.h
1 /*
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.
6  *
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.
11  *
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
15  */
16
17 /*
18  *    Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
19  *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
20  */
21
22 #pragma once
23
24 #include "stg/plugin.h"
25 #include "stg/module_settings.h"
26 #include "stg/notifer.h"
27 #include "stg/user.h"
28 #include "stg/blowfish.h"
29 #include "stg/rs_packets.h"
30 #include "stg/logger.h"
31
32 #include "nrmap_parser.h"
33
34 #include <string>
35 #include <list>
36 #include <map>
37 #include <functional>
38 #include <utility>
39 #include <mutex>
40 #pragma GCC diagnostic push
41 #pragma GCC diagnostic ignored "-Wshadow"
42 #include <jthread.hpp>
43 #pragma GCC diagnostic pop
44 #include <cstdint>
45
46 namespace STG
47 {
48 struct Settings;
49 struct Settings;
50 }
51
52 namespace RS
53 {
54
55 class REMOTE_SCRIPT;
56 class UpdateRouter;
57 class DisconnectUser;
58
59 using UserPtr = STG::User*;
60
61 //-----------------------------------------------------------------------------
62 class ADD_USER_NONIFIER: public STG::NotifierBase<UserPtr> {
63 public:
64     explicit ADD_USER_NONIFIER(REMOTE_SCRIPT & r)
65         : rs(r) {}
66     void Notify(const UserPtr & user);
67
68 private:
69     ADD_USER_NONIFIER(const ADD_USER_NONIFIER & rhs);
70     ADD_USER_NONIFIER & operator=(const ADD_USER_NONIFIER);
71
72     REMOTE_SCRIPT & rs;
73 };
74 //-----------------------------------------------------------------------------
75 class DEL_USER_NONIFIER: public STG::NotifierBase<UserPtr> {
76 public:
77     explicit DEL_USER_NONIFIER(REMOTE_SCRIPT & r)
78         : rs(r) {}
79     void Notify(const UserPtr & user);
80
81 private:
82     DEL_USER_NONIFIER(const DEL_USER_NONIFIER & rhs);
83     DEL_USER_NONIFIER & operator=(const DEL_USER_NONIFIER);
84
85     REMOTE_SCRIPT & rs;
86 };
87 //-----------------------------------------------------------------------------
88 class IP_NOTIFIER: public STG::PropertyNotifierBase<uint32_t> {
89 public:
90     IP_NOTIFIER(REMOTE_SCRIPT & r, UserPtr u)
91         : user(u), rs(r) { user->AddCurrIPAfterNotifier(this); }
92     IP_NOTIFIER(const IP_NOTIFIER & rhs)
93         : user(rhs.user), rs(rhs.rs) { user->AddCurrIPAfterNotifier(this); }
94     ~IP_NOTIFIER() { user->DelCurrIPAfterNotifier(this); }
95
96     IP_NOTIFIER & operator=(const IP_NOTIFIER & rhs)
97     {
98         user->DelCurrIPAfterNotifier(this);
99         user = rhs.user;
100         user->AddCurrIPAfterNotifier(this);
101         return *this;
102     }
103
104     void Notify(const uint32_t & oldValue, const uint32_t & newValue);
105     UserPtr GetUser() const { return user; }
106
107 private:
108
109     UserPtr user;
110     REMOTE_SCRIPT & rs;
111 };
112 //-----------------------------------------------------------------------------
113 class CONNECTED_NOTIFIER: public STG::PropertyNotifierBase<bool> {
114 public:
115     CONNECTED_NOTIFIER(REMOTE_SCRIPT & r, UserPtr u)
116         : user(u), rs(r) { user->AddConnectedAfterNotifier(this); }
117     CONNECTED_NOTIFIER(const CONNECTED_NOTIFIER & rhs)
118         : user(rhs.user), rs(rhs.rs) { user->AddConnectedAfterNotifier(this); }
119     ~CONNECTED_NOTIFIER() { user->DelConnectedAfterNotifier(this); }
120
121     CONNECTED_NOTIFIER & operator=(const CONNECTED_NOTIFIER & rhs)
122     {
123         user->DelConnectedAfterNotifier(this);
124         user = rhs.user;
125         user->AddConnectedAfterNotifier(this);
126         return *this;
127     }
128
129     void Notify(const bool & oldValue, const bool & newValue);
130     UserPtr GetUser() const { return user; }
131
132 private:
133
134     UserPtr user;
135     REMOTE_SCRIPT & rs;
136 };
137 //-----------------------------------------------------------------------------
138 struct USER {
139     USER(const std::vector<uint32_t> & r, UserPtr it)
140         : lastSentTime(0),
141           user(it),
142           routers(r),
143           shortPacketsCount(0),
144           ip(user->GetCurrIP())
145     {}
146
147     time_t lastSentTime;
148     UserPtr user;
149     std::vector<uint32_t> routers;
150     int shortPacketsCount;
151     uint32_t ip;
152 };
153 //-----------------------------------------------------------------------------
154 class SETTINGS {
155 public:
156                         SETTINGS();
157     virtual             ~SETTINGS() {}
158     const std::string & GetStrError() const { return errorStr; }
159     int                 ParseSettings(const STG::ModuleSettings & s);
160     int                 GetSendPeriod() const { return sendPeriod; }
161     uint16_t            GetPort() const { return port; }
162     const std::vector<NET_ROUTER> & GetSubnetsMap() const { return netRouters; }
163     const std::vector<std::string> & GetUserParams() const { return userParams; }
164     const std::string & GetPassword() const { return password; }
165     const std::string & GetMapFileName() const { return subnetFile; }
166
167 private:
168     int                 sendPeriod;
169     uint16_t            port;
170     std::string         errorStr;
171     std::vector<NET_ROUTER> netRouters;
172     std::vector<std::string> userParams;
173     std::string         password;
174     std::string         subnetFile;
175 };
176 //-----------------------------------------------------------------------------
177 class REMOTE_SCRIPT : public STG::Plugin {
178 public:
179                         REMOTE_SCRIPT();
180
181     void                SetUsers(STG::Users * u) override { users = u; }
182     void                SetSettings(const STG::ModuleSettings & s) override { settings = s; }
183     int                 ParseSettings() override;
184
185     int                 Start() override;
186     int                 Stop() override;
187     int                 Reload(const STG::ModuleSettings & ms) override;
188     bool                IsRunning() override { return isRunning; }
189
190     const std::string & GetStrError() const override { return errorStr; }
191     std::string         GetVersion() const override { return "Remote script v 0.3"; }
192     uint16_t            GetStartPosition() const override { return 10; }
193     uint16_t            GetStopPosition() const override { return 10; }
194
195     void                DelUser(UserPtr u) { UnSetUserNotifiers(u); }
196     void                AddUser(UserPtr u) { SetUserNotifiers(u); }
197
198     void                AddRSU(UserPtr user);
199     void                DelRSU(UserPtr user);
200
201 private:
202     REMOTE_SCRIPT(const REMOTE_SCRIPT & rhs);
203     REMOTE_SCRIPT & operator=(const REMOTE_SCRIPT & rhs);
204
205     void                Run(std::stop_token token);
206     bool                PrepareNet();
207     bool                FinalizeNet();
208
209     bool                Send(USER & rsu, bool forceDisconnect = false) const;
210     bool                SendDirect(USER & rsu, uint32_t routerIP, bool forceDisconnect = false) const;
211     bool                PreparePacket(char * buf, size_t bufSize, USER &rsu, bool forceDisconnect = false) const;
212     void                PeriodicSend();
213
214     std::vector<uint32_t> IP2Routers(uint32_t ip);
215     bool                GetUsers();
216
217     void                SetUserNotifiers(UserPtr u);
218     void                UnSetUserNotifiers(UserPtr u);
219
220     void                InitEncrypt(const std::string & password) const;
221     void                Encrypt(void * dst, const void * src, size_t len8) const;
222
223     mutable BLOWFISH_CTX ctx;
224
225     std::list<IP_NOTIFIER> ipNotifierList;
226     std::list<CONNECTED_NOTIFIER> connNotifierList;
227     std::map<uint32_t, USER> authorizedUsers;
228
229     mutable std::string errorStr;
230     SETTINGS         rsSettings;
231     STG::ModuleSettings     settings;
232     int                 sendPeriod;
233     int                 halfPeriod;
234
235     bool                isRunning;
236
237     STG::Users *             users;
238
239     std::vector<NET_ROUTER> netRouters;
240
241     std::jthread        m_thread;
242     std::mutex          m_mutex;
243
244     int                 sock;
245
246     ADD_USER_NONIFIER onAddUserNotifier;
247     DEL_USER_NONIFIER onDelUserNotifier;
248
249     STG::PluginLogger       logger;
250
251     friend class RS::UpdateRouter;
252     friend class RS::DisconnectUser;
253     friend class RS::CONNECTED_NOTIFIER;
254 };
255 //-----------------------------------------------------------------------------
256 class DisconnectUser : public std::unary_function<std::pair<const uint32_t, USER> &, void> {
257     public:
258         explicit DisconnectUser(REMOTE_SCRIPT & rs) : rscript(rs) {}
259         void operator()(std::pair<const uint32_t, USER> & p)
260         {
261             rscript.Send(p.second, true);
262         }
263     private:
264         REMOTE_SCRIPT & rscript;
265 };
266 //-----------------------------------------------------------------------------
267 inline void ADD_USER_NONIFIER::Notify(const UserPtr & user)
268 {
269 rs.AddUser(user);
270 }
271 //-----------------------------------------------------------------------------
272 inline void DEL_USER_NONIFIER::Notify(const UserPtr & user)
273 {
274 rs.DelUser(user);
275 }
276 //-----------------------------------------------------------------------------
277
278 } // namespace RS