X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/34ef822e81b9f236b2f5edf52d351a0f82d59a0c..d1b858e20ffcf99c42a9943e44fc13fb84571d64:/projects/sgauthstress/proto.cpp diff --git a/projects/sgauthstress/proto.cpp b/projects/sgauthstress/proto.cpp index 7c547daf..d4624594 100644 --- a/projects/sgauthstress/proto.cpp +++ b/projects/sgauthstress/proto.cpp @@ -5,18 +5,28 @@ #include #include #include +#include #include "stg/common.h" +#include "stg/ia_packets.h" #include "proto.h" +class HasIP : public std::unary_function, bool> { + public: + explicit HasIP(uint32_t i) : ip(i) {} + bool operator()(const std::pair & value) { return value.first == ip; } + private: + uint32_t ip; +}; + PROTO::PROTO(const std::string & server, uint16_t port, uint16_t localPort, int to) - : running(false), - stopped(true), - timeout(to) + : timeout(to), + running(false), + stopped(true) { uint32_t ip = inet_addr(server.c_str()); if (ip == INADDR_NONE) @@ -65,6 +75,7 @@ void * PROTO::Runner(void * data) { PROTO * protoPtr = static_cast(data); protoPtr->Run(); +return NULL; } bool PROTO::Start() @@ -109,38 +120,45 @@ if (pthread_join(tid, NULL)) return true; } -void PROTO::AddUser(const USER & user) +void PROTO::AddUser(const USER & user, bool connect) { - users.insert(std::make_pair(user.GetIP(), user)); - struct pollfd pfd; - pfd.fd = user.GetSocket(); - pfd.events = POLLIN; - pfd.revents = 0; - pollFds.push_back(pfd); +users.push_back(std::make_pair(user.GetIP(), user)); +struct pollfd pfd; +pfd.fd = user.GetSocket(); +pfd.events = POLLIN; +pfd.revents = 0; +pollFds.push_back(pfd); + +users.back().second.InitNetwork(); + +if (connect) + { + RealConnect(&users.back().second); + } } bool PROTO::Connect(uint32_t ip) { -std::map::const_iterator it; -it = users.find(ip); +std::vector >::iterator it; +it = std::find_if(users.begin(), users.end(), HasIP(ip)); if (it == users.end()) return false; // Do something -return true; +return RealConnect(&it->second); } bool PROTO::Disconnect(uint32_t ip) { -std::map::const_iterator it; -it = users.find(ip); +std::vector >::iterator it; +it = std::find_if(users.begin(), users.end(), HasIP(ip)); if (it == users.end()) return false; // Do something -return true; +return RealDisconnect(&it->second); } void PROTO::Run() @@ -163,8 +181,8 @@ bool PROTO::RecvPacket() { bool result = true; std::vector::iterator it; -std::map::iterator userIt(users.begin()); -for (it = pollFds.begin(); it != pollFds.end(); ++it) +std::vector >::iterator userIt; +for (it = pollFds.begin(), userIt = users.begin(); it != pollFds.end() && userIt != users.end(); ++it, ++userIt) { if (it->revents) { @@ -173,18 +191,16 @@ for (it = pollFds.begin(); it != pollFds.end(); ++it) struct sockaddr_in addr; socklen_t fromLen = sizeof(addr); char buffer[2048]; - int res = recvfrom(userIt->second.GetSocket(), buffer, sizeof(buffer), 0, (struct sockaddr*)&addr, &fromLen); + int res = recvfrom(userIt->second.GetSocket(), buffer, sizeof(buffer), 0, (struct sockaddr *)&addr, &fromLen); if (res == -1) { result = false; - ++userIt; continue; } result = result && HandlePacket(buffer, &(userIt->second)); } - ++userIt; } return result; @@ -203,6 +219,8 @@ it = processors.find(packetName); if (it != processors.end()) return (this->*it->second)(buffer, user); +printfd(__FILE__, "PROTO::HandlePacket() - invalid packet signature: '%s'\n", packetName.c_str()); + return false; } @@ -233,6 +251,8 @@ user->SetAliveTimeout(aliveTimeout); user->SetUserTimeout(userTimeout); user->SetRnd(rnd); +printfd(__FILE__, "PROTO::CONN_SYN_ACK_Proc() - user '%s' successfully logged in from IP %s\n", user->GetLogin().c_str(), inet_ntostring(user->GetIP()).c_str()); + return true; } @@ -319,9 +339,10 @@ return true; bool PROTO::ERR_Proc(const void * buffer, USER * user) { const ERR_8 * packet = static_cast(buffer); +const char * ptr = static_cast(buffer); -for (int i = 0; i < len/8; i++) - Blowfish_Decrypt(&ctxPass, (uint32_t*)(buffer + i*8), (uint32_t*)(buffer + i*8 + 4)); +for (size_t i = 0; i < sizeof(ERR_8) / 8; i++) + Blowfish_Decrypt(user->GetCtx(), (uint32_t *)(ptr + i * 8), (uint32_t *)(ptr + i * 8 + 4)); //uint32_t len = packet->len; @@ -435,7 +456,7 @@ assert(sizeof(hdr) + length < 2048 && "Packet length must not exceed 2048 bytes" strncpy((char *)hdr.magic, IA_ID, 6); hdr.protoVer[0] = 0; -hdr.protoVer[1] = IA_PROTO_VER; +hdr.protoVer[1] = 8; // IA_PROTO_VER unsigned char buffer[2048]; memcpy(buffer, &hdr, sizeof(hdr)); @@ -465,7 +486,7 @@ if (res < 0) errorStr = "Failed to send packet: '"; errorStr += strerror(errno); errorStr += "'"; - printfd(__FILE__, "PROTO::SendPacket() - %s\n", errorStr.c_str()); + printfd(__FILE__, "PROTO::SendPacket() - %s, fd: %d\n", errorStr.c_str(), user->GetSocket()); return false; } @@ -478,3 +499,28 @@ if (res < sizeof(buffer)) return true; } + +bool PROTO::RealConnect(USER * user) +{ +if (user->GetPhase() != 1 && + user->GetPhase() != 5) + { + errorStr = "Unexpected connect"; + printfd(__FILE__, "PROTO::RealConnect() - wrong phase: %d\n", user->GetPhase()); + } +user->SetPhase(2); + +return Send_CONN_SYN(user); +} + +bool PROTO::RealDisconnect(USER * user) +{ +if (user->GetPhase() != 3) + { + errorStr = "Unexpected disconnect"; + printfd(__FILE__, "PROTO::RealDisconnect() - wrong phase: %d\n", user->GetPhase()); + } +user->SetPhase(4); + +return Send_DISCONN_SYN(user); +}