X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/641204dfbdb9fc870cdd2e7f9e3169a44693e7bf..2574a28cbf000603bc31f61593dbf061ff56c1d5:/projects/stargazer/plugins/configuration/rpcconfig/rpcconfig.cpp?ds=sidebyside diff --git a/projects/stargazer/plugins/configuration/rpcconfig/rpcconfig.cpp b/projects/stargazer/plugins/configuration/rpcconfig/rpcconfig.cpp index c059ba61..df5ae9e4 100644 --- a/projects/stargazer/plugins/configuration/rpcconfig/rpcconfig.cpp +++ b/projects/stargazer/plugins/configuration/rpcconfig/rpcconfig.cpp @@ -1,86 +1,62 @@ #include "rpcconfig.h" -#include -#include #include "info_methods.h" #include "users_methods.h" #include "tariffs_methods.h" #include "admins_methods.h" #include "messages_methods.h" -class RPC_CONFIG_CREATOR -{ -private: - RPC_CONFIG * rpcconfig; +#include "stg/admins.h" +#include "stg/admin.h" +#include "stg/module_settings.h" +#include "stg/settings.h" +#include "stg/common.h" +#include "stg/const.h" -public: - RPC_CONFIG_CREATOR() - : rpcconfig(new RPC_CONFIG()) - { - }; - ~RPC_CONFIG_CREATOR() - { - delete rpcconfig; - }; - - RPC_CONFIG * GetPlugin() - { - return rpcconfig; - }; -}; +#include +#include +#include // xmlrpc-c devs have missed something :) +#include +#include +#include +#include -RPC_CONFIG_CREATOR rpcc; +#include +#include +#include +#include +#include RPC_CONFIG_SETTINGS::RPC_CONFIG_SETTINGS() - : errorStr(), - port(0), + : port(0), cookieTimeout(0) { } -int RPC_CONFIG_SETTINGS::ParseIntInRange(const string & str, - int min, - int max, - int * val) +int RPC_CONFIG_SETTINGS::ParseSettings(const STG::ModuleSettings & s) { -if (str2x(str.c_str(), *val)) - { - errorStr = "Incorrect value \'" + str + "\'."; - return -1; - } -if (*val < min || *val > max) - { - errorStr = "Value \'" + str + "\' out of range."; - return -1; - } -return 0; -} - -int RPC_CONFIG_SETTINGS::ParseSettings(const MODULE_SETTINGS & s) -{ -int p; -PARAM_VALUE pv; -vector::const_iterator pvi; - +STG::ParamValue pv; pv.param = "Port"; -pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv); -if (pvi == s.moduleParams.end()) +std::vector::const_iterator pvi; +pvi = std::find(s.moduleParams.begin(), s.moduleParams.end(), pv); +if (pvi == s.moduleParams.end() || pvi->value.empty()) { errorStr = "Parameter \'Port\' not found."; printfd(__FILE__, "Parameter 'Port' not found\n"); return -1; } +int p; if (ParseIntInRange(pvi->value[0], 2, 65535, &p)) { errorStr = "Cannot parse parameter \'Port\': " + errorStr; printfd(__FILE__, "Cannot parse parameter 'Port'\n"); return -1; } -port = p; +port = static_cast(p); pv.param = "CookieTimeout"; -pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv); -if (pvi == s.moduleParams.end()) +pvi = std::find(s.moduleParams.begin(), s.moduleParams.end(), pv); +if (pvi == s.moduleParams.end() || pvi->value.empty()) { cookieTimeout = 1800; // 30 * 60 } @@ -97,15 +73,23 @@ else return 0; } -BASE_PLUGIN * GetPlugin() +extern "C" STG::Plugin* GetPlugin() { -return rpcc.GetPlugin(); + static RPC_CONFIG plugin; + return &plugin; } RPC_CONFIG::RPC_CONFIG() - : rpcServer(NULL) + : users(NULL), + admins(NULL), + tariffs(NULL), + store(NULL), + fd(-1), + rpcServer(NULL), + stopped(true), + dayFee(0), + logger(STG::PluginLogger::get("conf_rpc")) { - } RPC_CONFIG::~RPC_CONFIG() @@ -124,65 +108,109 @@ if (ret) return ret; } +void RPC_CONFIG::SetStgSettings(const STG::Settings * s) +{ + dayFee = s->GetDayFee(); + dirNames.erase(dirNames.begin(), dirNames.end()); + for (size_t i = 0; i < DIR_NUM; ++i) { + dirNames.push_back(s->GetDirName(i)); + } +} + int RPC_CONFIG::Start() { InitiateRegistry(); -running = true; -rpcServer = new xmlrpc_c::serverAbyss( - rpcRegistry, - rpcConfigSettings.GetPort(), - "/var/log/stargazer_rpc.log" - ); -if (pthread_create(&tid, NULL, Run, this)) + +fd = socket(AF_INET, SOCK_STREAM, 0); +if (fd < 0) + { + errorStr = "Failed to create socket"; + logger("Cannot create a socket: %s", strerror(errno)); + printfd(__FILE__, "Failed to create listening socket: %s\n", strerror(errno)); + return -1; + } + +int flag = 1; + +if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag))) { - errorStr = "Failed to create RPC thread"; - printfd(__FILE__, "Failed to crate RPC thread\n"); + errorStr = "Setsockopt failed."; + logger("setsockopt error: %s", strerror(errno)); + printfd(__FILE__, "Setsockopt failed: %s\n", strerror(errno)); return -1; } + +struct sockaddr_in addr; +addr.sin_family = AF_INET; +addr.sin_port = htons(rpcConfigSettings.GetPort()); +addr.sin_addr.s_addr = inet_addr("0.0.0.0"); + +if (bind(fd, reinterpret_cast(&addr), sizeof(addr))) + { + logger("Cannot bind the socket: %s", strerror(errno)); + errorStr = "Failed to bind socket"; + printfd(__FILE__, "Failed to bind listening socket: %s\n", strerror(errno)); + return -1; + } + +if (listen(fd, 10)) + { + logger("Cannot listen the socket: %s", strerror(errno)); + errorStr = "Failed to listen socket"; + printfd(__FILE__, "Failed to listen listening socket: %s\n", strerror(errno)); + return -1; + } + +rpcServer = new xmlrpc_c::serverAbyss( + xmlrpc_c::serverAbyss::constrOpt() + .registryP(&rpcRegistry) + .logFileName("/var/log/stargazer_rpc.log") + .socketFd(fd) + ); + +m_thread = std::jthread([this](auto token){ Run(std::move(token)); }); + return 0; } int RPC_CONFIG::Stop() { -running = false; +m_thread.request_stop(); for (int i = 0; i < 5 && !stopped; ++i) - usleep(200000); -//rpcServer->terminate(); + { + struct timespec ts = {0, 200000000}; + nanosleep(&ts, NULL); + } + if (!stopped) { - if (pthread_kill(tid, SIGTERM)) - { - errorStr = "Failed to kill thread"; - printfd(__FILE__, "Failed to kill thread\n"); - } - for (int i = 0; i < 25 && !stopped; ++i) - usleep(200000); - if (!stopped) - { - printfd(__FILE__, "Failed to stop RPC thread\n"); - errorStr = "Failed to stop RPC thread"; - return -1; - } - else - { - pthread_join(tid, NULL); - } + m_thread.detach(); + logger("Cannot stop RPC thread."); + printfd(__FILE__, "Failed to stop RPC thread\n"); + errorStr = "Failed to stop RPC thread"; + return -1; } +else + m_thread.join(); + +close(fd); + return 0; } -void * RPC_CONFIG::Run(void * rc) +void RPC_CONFIG::Run(std::stop_token token) { -RPC_CONFIG * config = static_cast(rc); +sigset_t signalSet; +sigfillset(&signalSet); +pthread_sigmask(SIG_BLOCK, &signalSet, NULL); -config->stopped = false; -while (config->running) +stopped = false; +while (!token.stop_requested()) { - config->rpcServer->runOnce(); + if (WaitPackets(fd)) + rpcServer->runOnce(); } -config->stopped = true; - -return NULL; +stopped = true; } bool RPC_CONFIG::GetAdminInfo(const std::string & cookie, @@ -215,17 +243,18 @@ bool RPC_CONFIG::CheckAdmin(const std::string & login, const std::string & password, std::string * cookie) { -ADMIN admin; +STG::Admin * admin = NULL; -if (!admins->AdminCorrect(login, password, &admin)) +if (!admins->correct(login, password, &admin)) { + logger("Attempt to connect with invalid credentials. Login: %s", login.c_str()); return true; } ADMIN_INFO info; time(&info.accessTime); info.admin = login; -info.priviledges = *admin.GetPriv(); +info.priviledges = admin->priv(); *cookie = GetCookie(); cookies[*cookie] = info; @@ -268,7 +297,8 @@ void RPC_CONFIG::InitiateRegistry() xmlrpc_c::methodPtr const methodInfoPtr(new METHOD_INFO( tariffs, users, - stgSettings + dayFee, + dirNames )); rpcRegistry.addMethod("stargazer.info", methodInfoPtr); @@ -311,6 +341,7 @@ rpcRegistry.addMethod("stargazer.get_users", methodGetUsersPtr); xmlrpc_c::methodPtr const methodChgUserPtr(new METHOD_USER_CHG( this, admins, + tariffs, store, users )); @@ -322,7 +353,7 @@ xmlrpc_c::methodPtr const methodAddCashPtr(new METHOD_USER_CASH_ADD( store, users )); -rpcRegistry.addMethod("stargazer.add_cash", methodAddCashPtr); +rpcRegistry.addMethod("stargazer.add_user_cash", methodAddCashPtr); xmlrpc_c::methodPtr const methodSetCashPtr(new METHOD_USER_CASH_SET( this, @@ -330,7 +361,7 @@ xmlrpc_c::methodPtr const methodSetCashPtr(new METHOD_USER_CASH_SET( store, users )); -rpcRegistry.addMethod("stargazer.set_cash", methodSetCashPtr); +rpcRegistry.addMethod("stargazer.set_user_cash", methodSetCashPtr); xmlrpc_c::methodPtr const methodTariffChangePtr(new METHOD_USER_TARIFF_CHANGE( this, @@ -339,7 +370,7 @@ xmlrpc_c::methodPtr const methodTariffChangePtr(new METHOD_USER_TARIFF_CHANGE( store, users )); -rpcRegistry.addMethod("stargazer.tariff_change", methodTariffChangePtr); +rpcRegistry.addMethod("stargazer.chg_user_tariff", methodTariffChangePtr); xmlrpc_c::methodPtr const methodGetTariffPtr(new METHOD_TARIFF_GET( this, @@ -409,12 +440,18 @@ xmlrpc_c::methodPtr const methodSendMessagePtr(new METHOD_MESSAGE_SEND( this, users )); -rpcRegistry.addMethod("stargazer.send_message", methodSendMessagePtr); +rpcRegistry.addMethod("stargazer.send_user_message", methodSendMessagePtr); xmlrpc_c::methodPtr const methodGetOnlinIPsPtr(new METHOD_GET_ONLINE_IPS( this, users )); rpcRegistry.addMethod("stargazer.get_online_ips", methodGetOnlinIPsPtr); + +xmlrpc_c::methodPtr const methodGetUserAuthByPtr(new METHOD_GET_USER_AUTH_BY( + this, + users + )); +rpcRegistry.addMethod("stargazer.get_user_auth_by", methodGetUserAuthByPtr); }