X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/641204dfbdb9fc870cdd2e7f9e3169a44693e7bf..8c6fa3fbaccc22127280bf77a48fab5a3ee0716e:/projects/rscriptd/listener.cpp diff --git a/projects/rscriptd/listener.cpp b/projects/rscriptd/listener.cpp index 87a85ebb..0b626afd 100644 --- a/projects/rscriptd/listener.cpp +++ b/projects/rscriptd/listener.cpp @@ -27,15 +27,19 @@ #include #include +#include #include #include #include #include +#include "stg/scriptexecuter.h" +#include "stg/locker.h" +#include "stg/common.h" #include "listener.h" -#include "script_executer.h" -#include "stg_locker.h" -#include "common.h" + +void InitEncrypt(BLOWFISH_CTX * ctx, const std::string & password); +void Decrypt(BLOWFISH_CTX * ctx, char * dst, const char * src, int len8); //----------------------------------------------------------------------------- LISTENER::LISTENER() @@ -45,14 +49,13 @@ LISTENER::LISTENER() receiverStopped(true), processorStopped(true), userTimeout(0), - listenSocket(0) + listenSocket(0), + version("rscriptd listener v.1.2") { -version = "rscriptd listener v.1.2"; - pthread_mutex_init(&mutex, NULL); } //----------------------------------------------------------------------------- -void LISTENER::SetPassword(const string & p) +void LISTENER::SetPassword(const std::string & p) { password = p; printfd(__FILE__, "Encryption initiated with password \'%s\'\n", password.c_str()); @@ -98,14 +101,16 @@ running = false; printfd(__FILE__, "LISTENER::Stop()\n"); -usleep(500000); +struct timespec ts = {0, 500000000}; +nanosleep(&ts, NULL); if (!processorStopped) { //5 seconds to thread stops itself for (int i = 0; i < 25 && !processorStopped; i++) { - usleep(200000); + struct timespec ts = {0, 200000000}; + nanosleep(&ts, NULL); } //after 5 seconds waiting thread still running. now killing it @@ -126,7 +131,8 @@ if (!receiverStopped) //5 seconds to thread stops itself for (int i = 0; i < 25 && !receiverStopped; i++) { - usleep(200000); + struct timespec ts = {0, 200000000}; + nanosleep(&ts, NULL); } //after 5 seconds waiting thread still running. now killing it @@ -158,9 +164,13 @@ return false; //----------------------------------------------------------------------------- void * LISTENER::Run(void * d) { -LISTENER * ia = static_cast(d); +sigset_t signalSet; +sigfillset(&signalSet); +pthread_sigmask(SIG_BLOCK, &signalSet, NULL); -ia->Runner(); +LISTENER * listener = static_cast(d); + +listener->Runner(); return NULL; } @@ -179,9 +189,13 @@ receiverStopped = true; //----------------------------------------------------------------------------- void * LISTENER::RunProcessor(void * d) { -LISTENER * ia = static_cast(d); +sigset_t signalSet; +sigfillset(&signalSet); +pthread_sigmask(SIG_BLOCK, &signalSet, NULL); + +LISTENER * listener = static_cast(d); -ia->ProcessorRunner(); +listener->ProcessorRunner(); return NULL; } @@ -192,7 +206,8 @@ processorStopped = false; while (running) { - usleep(500000); + struct timespec ts = {0, 500000000}; + nanosleep(&ts, NULL); if (!pending.empty()) ProcessPending(); ProcessTimeouts(); @@ -211,8 +226,6 @@ if (listenSocket < 0) return true; } -printfd(__FILE__, "Port: %d\n", port); - struct sockaddr_in listenAddr; listenAddr.sin_family = AF_INET; listenAddr.sin_port = htons(port); @@ -241,12 +254,12 @@ bool LISTENER::RecvPacket() struct iovec iov[2]; char buffer[RS_MAX_PACKET_LEN]; -RS_PACKET_HEADER packetHead; +RS::PACKET_HEADER packetHead; iov[0].iov_base = reinterpret_cast(&packetHead); iov[0].iov_len = sizeof(packetHead); iov[1].iov_base = buffer; -iov[1].iov_len = sizeof(buffer); +iov[1].iov_len = sizeof(buffer) - sizeof(packetHead); size_t dataLen = 0; while (dataLen < sizeof(buffer)) @@ -298,7 +311,7 @@ else if (packetHead.packetType == RS_DISCONNECT_PACKET) } } -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); pending.push_back(data); return false; @@ -306,7 +319,7 @@ return false; //----------------------------------------------------------------------------- bool LISTENER::GetParams(char * buffer, UserData & data) { -RS_PACKET_TAIL packetTail; +RS::PACKET_TAIL packetTail; Decrypt(&ctxS, (char *)&packetTail, buffer, sizeof(packetTail) / 8); @@ -316,10 +329,10 @@ if (strncmp((char *)packetTail.magic, RS_ID, RS_MAGIC_LEN)) return true; } -std::stringstream params; -params << data.login << " " +std::ostringstream params; +params << "\"" << data.login << "\" " << inet_ntostring(data.ip) << " " - << ntohl(data.id) << " " + << data.id << " " << (char *)packetTail.params; data.params = params.str(); @@ -329,9 +342,10 @@ return false; //----------------------------------------------------------------------------- void LISTENER::ProcessPending() { -printfd(__FILE__, "Pending data size: %d\n", pending.size()); std::list::iterator it(pending.begin()); -while (it != pending.end()) +size_t count = 0; +printfd(__FILE__, "Pending: %d\n", pending.size()); +while (it != pending.end() && count < 256) { std::vector::iterator uit( std::lower_bound( @@ -341,40 +355,65 @@ while (it != pending.end()) ); if (it->type == PendingData::CONNECT) { + printfd(__FILE__, "Connect packet\n"); if (uit == users.end() || uit->login != it->login) { + printfd(__FILE__, "Connect new user '%s'\n", it->login.c_str()); // Add new user Connect(*it); users.insert(uit, AliveData(static_cast(*it))); } else if (uit->login == it->login) { + printfd(__FILE__, "Update existing user '%s'\n", it->login.c_str()); // Update already existing user time(&uit->lastAlive); uit->params = it->params; } + else + { + printfd(__FILE__, "Hmmm... Strange connect for '%s'\n", it->login.c_str()); + } } else if (it->type == PendingData::ALIVE) { + printfd(__FILE__, "Alive packet\n"); if (uit != users.end() && uit->login == it->login) { + printfd(__FILE__, "Alive user '%s'\n", it->login.c_str()); // Update existing user time(&uit->lastAlive); } + else + { + printfd(__FILE__, "Alive user '%s' is not found\n", it->login.c_str()); + } } else if (it->type == PendingData::DISCONNECT) { + printfd(__FILE__, "Disconnect packet\n"); if (uit != users.end() && uit->login == it->login.c_str()) { + printfd(__FILE__, "Disconnect user '%s'\n", it->login.c_str()); // Disconnect existing user + uit->params = it->params; Disconnect(*uit); users.erase(uit); } + else + { + printfd(__FILE__, "Cannot find user '%s' for disconnect\n", it->login.c_str()); + } } - - STG_LOCKER lock(&mutex, __FILE__, __LINE__); - pending.erase(it++); + else + { + printfd(__FILE__, "Unknown packet type\n"); + } + ++it; + ++count; } +STG_LOCKER lock(&mutex); +pending.erase(pending.begin(), it); } //----------------------------------------------------------------------------- void LISTENER::ProcessTimeouts() @@ -406,7 +445,7 @@ bool LISTENER::Connect(const UserData & data) const printfd(__FILE__, "Connect %s\n", data.login.c_str()); if (access(scriptOnConnect.c_str(), X_OK) == 0) { - if (ScriptExec(scriptOnConnect + " " + data.params)) + if (ScriptExec((scriptOnConnect + " " + data.params).c_str())) { WriteServLog("Script %s cannot be executed for an unknown reason.", scriptOnConnect.c_str()); return true; @@ -425,7 +464,7 @@ bool LISTENER::Disconnect(const UserData & data) const printfd(__FILE__, "Disconnect %s\n", data.login.c_str()); if (access(scriptOnDisconnect.c_str(), X_OK) == 0) { - if (ScriptExec(scriptOnDisconnect + " " + data.params)) + if (ScriptExec((scriptOnDisconnect + " " + data.params).c_str())) { WriteServLog("Script %s cannot be executed for an unknown reson.", scriptOnDisconnect.c_str()); return true; @@ -439,24 +478,7 @@ else return false; } //----------------------------------------------------------------------------- -void LISTENER::InitEncrypt(BLOWFISH_CTX * ctx, const string & password) -{ -unsigned char keyL[PASSWD_LEN]; -memset(keyL, 0, PASSWD_LEN); -strncpy((char *)keyL, password.c_str(), PASSWD_LEN); -Blowfish_Init(ctx, keyL, PASSWD_LEN); -} -//----------------------------------------------------------------------------- -void LISTENER::Decrypt(BLOWFISH_CTX * ctx, char * dst, const char * src, int len8) -{ -if (dst != src) - memcpy(dst, src, len8 * 8); - -for (int i = 0; i < len8; i++) - Blowfish_Decrypt(ctx, (uint32_t *)(dst + i * 8), (uint32_t *)(dst + i * 8 + 4)); -} -//----------------------------------------------------------------------------- -bool LISTENER::CheckHeader(const RS_PACKET_HEADER & header) const +bool LISTENER::CheckHeader(const RS::PACKET_HEADER & header) const { if (strncmp((char *)header.magic, RS_ID, RS_MAGIC_LEN)) { @@ -469,31 +491,22 @@ if (strncmp((char *)header.protoVer, "02", RS_PROTO_VER_LEN)) return false; } //----------------------------------------------------------------------------- -bool LISTENER::WaitPackets(int sd) const +inline +void InitEncrypt(BLOWFISH_CTX * ctx, const std::string & password) { -fd_set rfds; -FD_ZERO(&rfds); -FD_SET(sd, &rfds); - -struct timeval tv; -tv.tv_sec = 0; -tv.tv_usec = 500000; - -int res = select(sd + 1, &rfds, NULL, NULL, &tv); -if (res == -1) // Error - { - if (errno != EINTR) - { - printfd(__FILE__, "Error on select: '%s'\n", strerror(errno)); - } - return false; - } - -if (res == 0) // Timeout - { - return false; - } +unsigned char keyL[PASSWD_LEN]; +memset(keyL, 0, PASSWD_LEN); +strncpy((char *)keyL, password.c_str(), PASSWD_LEN); +Blowfish_Init(ctx, keyL, PASSWD_LEN); +} +//----------------------------------------------------------------------------- +inline +void Decrypt(BLOWFISH_CTX * ctx, char * dst, const char * src, int len8) +{ +if (dst != src) + memcpy(dst, src, len8 * 8); -return true; +for (int i = 0; i < len8; i++) + Blowfish_Decrypt(ctx, (uint32_t *)(dst + i * 8), (uint32_t *)(dst + i * 8 + 4)); } //-----------------------------------------------------------------------------