X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/4931ba9476c58923e2f9020bce6bc1a7ca40aaed..668e4a697bab5faa6a78e9708cff8bb1d4a36241:/stglibs/ia.lib/ia.cpp diff --git a/stglibs/ia.lib/ia.cpp b/stglibs/ia.lib/ia.cpp index 9883dbbb..a05d3061 100644 --- a/stglibs/ia.lib/ia.cpp +++ b/stglibs/ia.lib/ia.cpp @@ -29,25 +29,26 @@ //--------------------------------------------------------------------------- +#ifdef WIN32 +#include +#include +#include +#include +#else +#include +#include +#include +#include +#include +#endif + #include #include #include #include -#ifdef WIN32 - #include - #include - #include - #include -#else - #include - #include - #include - #include -#endif - #include "stg/common.h" -#include "ia.h" +#include "stg/ia.h" #define IA_NONE (0) #define IA_CONNECT (1) @@ -61,15 +62,25 @@ //--------------------------------------------------------------------------- #ifndef WIN32 #include +void Sleep(int ms) +{ +long long res = ms * 1000000; +struct timespec ts = {res / 1000000000, res % 1000000000}; +nanosleep(&ts, NULL); +} +//--------------------------------------------------------------------------- void * RunL(void * data) { +sigset_t signalSet; +sigfillset(&signalSet); +pthread_sigmask(SIG_BLOCK, &signalSet, NULL); IA_CLIENT_PROT * c = (IA_CLIENT_PROT *)data; static int a = 0; if (a == 0) { - usleep(50000); + Sleep(50); a = 1; } @@ -80,11 +91,6 @@ while (c->GetNonstop()) return NULL; } //--------------------------------------------------------------------------- -void Sleep(int ms) -{ -usleep(ms * 1000); -} -//--------------------------------------------------------------------------- long GetTickCount() { struct timeval tv; @@ -102,10 +108,36 @@ return 0; } //--------------------------------------------------------------------------- #endif + +namespace +{ + +bool HostNameToIP(const std::string & hostName, uint32_t & ip) +{ +ip = inet_addr(hostName.c_str()); +if (ip == INADDR_NONE) + { + hostent * phe = gethostbyname(hostName.c_str()); + if (phe) + { + ip = *((uint32_t *)phe->h_addr_list[0]); + } + else + { + return false; + } + } + +return true; +} + +} + //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- -IA_CLIENT_PROT::IA_CLIENT_PROT(const string & sn, unsigned short p, uint16_t localPort) +IA_CLIENT_PROT::IA_CLIENT_PROT(const std::string & sn, unsigned short p, + const std::string & ln, uint16_t lp) : action(IA_NONE), phase(1), phaseTime(0), @@ -116,7 +148,8 @@ IA_CLIENT_PROT::IA_CLIENT_PROT(const string & sn, unsigned short p, uint16_t loc serverName(sn), port(p), ip(0), - localPort(localPort), + localName(ln), + localPort(lp), firstConnect(true), reconnect(0), sockr(0), @@ -184,7 +217,7 @@ servAddr.sin_addr.s_addr = ip; //--------------------------------------------------------------------------- void IA_CLIENT_PROT::PrepareNet() { -struct hostent * phe; +/*struct hostent * phe; unsigned long ip; ip = inet_addr(serverName.c_str()); @@ -202,6 +235,16 @@ if (ip == INADDR_NONE) if (pErrorCb != NULL) pErrorCb(strError, IA_GETHOSTBYNAME_ERROR, errorCbData); } + }*/ + +if (!HostNameToIP(serverName, ip)) + { + ip = 0; + strError = std::string("Unknown host ") + "\'" + serverName + "\'"; + codeError = IA_GETHOSTBYNAME_ERROR; + if (pErrorCb != NULL) + pErrorCb(strError, IA_GETHOSTBYNAME_ERROR, errorCbData); + return; } #ifndef WIN32 @@ -219,7 +262,24 @@ if (localPort) localAddrR.sin_port = htons(localPort); else localAddrR.sin_port = htons(port); -localAddrR.sin_addr.s_addr = inet_addr("0.0.0.0"); + +if (!localName.empty()) + { + if (!HostNameToIP(localName, localIP)) + { + strError = std::string("Unknown host ") + "\'" + serverName + "\'"; + codeError = IA_GETHOSTBYNAME_ERROR; + if (pErrorCb != NULL) + pErrorCb(strError, IA_GETHOSTBYNAME_ERROR, errorCbData); + localIP = INADDR_ANY; + } + } +else + { + localIP = INADDR_ANY; + } + +localAddrR.sin_addr.s_addr = localIP; servAddr.sin_family = AF_INET; servAddr.sin_port = htons(port); @@ -237,7 +297,7 @@ if (res == -1) #ifdef WIN32 unsigned long arg = 1; -res = ioctlsocket(sockr, FIONBIO, &arg); +ioctlsocket(sockr, FIONBIO, &arg); #else if (0 != fcntl(sockr, F_SETFL, O_NONBLOCK)) { @@ -262,7 +322,7 @@ WSACleanup(); //--------------------------------------------------------------------------- int IA_CLIENT_PROT::DeterminatePacketType(const char * buffer) { -map::iterator pi; +std::map::iterator pi; pi = packetTypes.find(buffer); if (pi == packetTypes.end()) { @@ -291,18 +351,11 @@ if (!isNetPrepared) } int db = sizeof(HDR_8); -for (int i = 0; i < IA_LOGIN_LEN/8; i++) - { - Blowfish_Encrypt(&ctxHdr, (uint32_t*)(buffer + db + i*8), (uint32_t*)(buffer + db + i*8 + 4)); - } +EncryptString(buffer + db, buffer + db, IA_LOGIN_LEN, &ctxHdr); db += IA_LOGIN_LEN; -int encLen = (len - sizeof(HDR_8) - IA_LOGIN_LEN)/8; -for (int i = 0; i < encLen; i++) - { - Blowfish_Encrypt(&ctxPass, (uint32_t*)(buffer + db), (uint32_t*)(buffer + db + 4)); - db += 8; - } +int encLen = (len - sizeof(HDR_8) - IA_LOGIN_LEN); +EncryptString(buffer + db, buffer + db, encLen, &ctxPass); return sendto(sockr, buffer, len, 0, (struct sockaddr*)&servAddr, sizeof(servAddr)); } @@ -323,10 +376,7 @@ if (res == -1) return res; if (strcmp(buffer + 4 + sizeof(HDR_8), "ERR")) - { - for (int i = 0; i < len/8; i++) - Blowfish_Decrypt(&ctxPass, (uint32_t*)(buffer + i*8), (uint32_t*)(buffer + i*8 + 4)); - } + DecryptString(buffer, buffer, len, &ctxPass); return 0; } @@ -537,19 +587,19 @@ void IA_CLIENT_PROT::GetStat(LOADSTAT * ls) memcpy(ls, &stat, sizeof(stat)); } //--------------------------------------------------------------------------- -void IA_CLIENT_PROT::SetServer(const string & sn, unsigned short p) +void IA_CLIENT_PROT::SetServer(const std::string & sn, unsigned short p) { serverName = sn; port = p; PrepareNet(); } //--------------------------------------------------------------------------- -void IA_CLIENT_PROT::SetLogin(const string & l) +void IA_CLIENT_PROT::SetLogin(const std::string & l) { login = l; } //--------------------------------------------------------------------------- -void IA_CLIENT_PROT::SetPassword(const string & p) +void IA_CLIENT_PROT::SetPassword(const std::string & p) { password = p; @@ -577,7 +627,7 @@ action = IA_DISCONNECT; return 0; } //--------------------------------------------------------------------------- -int IA_CLIENT_PROT::GetStrError(string * error) const +int IA_CLIENT_PROT::GetStrError(std::string * error) const { int ret = codeError; *error = strError; @@ -588,7 +638,7 @@ return ret; //--------------------------------------------------------------------------- int IA_CLIENT_PROT::Process_CONN_SYN_ACK_8(const char * buffer) { -vector dirNames; +std::vector dirNames; connSynAck8 = (CONN_SYN_ACK_8*)buffer; #ifdef ARCH_BE @@ -714,13 +764,14 @@ int IA_CLIENT_PROT::Prepare_CONN_SYN_8(char * buffer) { connSyn8 = (CONN_SYN_8*)buffer; +assert(sizeof(CONN_SYN_8) == Min8(sizeof(CONN_SYN_8)) && "CONN_SYN_8 is not aligned to 8 bytes"); + +connSyn8->len = sizeof(CONN_SYN_8); + #ifdef ARCH_BE SwapBytes(connSyn8->len); #endif -assert(sizeof(CONN_SYN_8) == Min8(sizeof(CONN_SYN_8)) && "CONN_SYN_8 is not aligned to 8 bytes"); - -connSyn8->len = sizeof(CONN_SYN_8); strncpy((char*)connSyn8->type, "CONN_SYN", IA_MAX_TYPE_LEN); strncpy((char*)connSyn8->login, login.c_str(), IA_LOGIN_LEN); connSyn8->dirs = 0; @@ -728,18 +779,13 @@ for (int i = 0; i < DIR_NUM; i++) { connSyn8->dirs |= (selectedDirs[i] << i); } -return connSyn8->len; +return sizeof(CONN_SYN_8); } //--------------------------------------------------------------------------- int IA_CLIENT_PROT::Prepare_CONN_ACK_8(char * buffer) { connAck8 = (CONN_ACK_8*)buffer; -#ifdef ARCH_BE -SwapBytes(connAck8->len); -SwapBytes(connAck8->rnd); -#endif - assert(sizeof(CONN_ACK_8) == Min8(sizeof(CONN_ACK_8)) && "CONN_ACK_8 is not aligned to 8 bytes"); connAck8->len = sizeof(CONN_ACK_8); @@ -748,18 +794,18 @@ strncpy((char*)connAck8->type, "CONN_ACK", IA_MAX_TYPE_LEN); rnd++; connAck8->rnd = rnd; -return connAck8->len; +#ifdef ARCH_BE +SwapBytes(connAck8->len); +SwapBytes(connAck8->rnd); +#endif + +return sizeof(CONN_ACK_8); } //--------------------------------------------------------------------------- int IA_CLIENT_PROT::Prepare_ALIVE_ACK_8(char * buffer) { aliveAck8 = (ALIVE_ACK_8*)buffer; -#ifdef ARCH_BE -SwapBytes(aliveAck8->len); -SwapBytes(aliveAck8->rnd); -#endif - assert(Min8(sizeof(ALIVE_ACK_8)) == sizeof(ALIVE_ACK_8) && "ALIVE_ACK_8 is not aligned to 8 bytes"); aliveAck8 = (ALIVE_ACK_8*)buffer; @@ -767,42 +813,50 @@ aliveAck8->len = sizeof(ALIVE_ACK_8); strncpy((char*)aliveAck8->loginS, login.c_str(), IA_LOGIN_LEN); strncpy((char*)aliveAck8->type, "ALIVE_ACK", IA_MAX_TYPE_LEN); aliveAck8->rnd = ++rnd; -return aliveAck8->len; + +#ifdef ARCH_BE +SwapBytes(aliveAck8->len); +SwapBytes(aliveAck8->rnd); +#endif + +return sizeof(ALIVE_ACK_8); } //--------------------------------------------------------------------------- int IA_CLIENT_PROT::Prepare_DISCONN_SYN_8(char * buffer) { disconnSyn8 = (DISCONN_SYN_8*)buffer; +assert(Min8(sizeof(DISCONN_SYN_8)) == sizeof(DISCONN_SYN_8) && "DISCONN_SYN_8 is not aligned to 8 bytes"); + +disconnSyn8->len = sizeof(DISCONN_SYN_8); + #ifdef ARCH_BE SwapBytes(disconnSyn8->len); #endif -assert(Min8(sizeof(DISCONN_SYN_8)) == sizeof(DISCONN_SYN_8) && "DISCONN_SYN_8 is not aligned to 8 bytes"); - -disconnSyn8->len = sizeof(DISCONN_SYN_8); strncpy((char*)disconnSyn8->loginS, login.c_str(), IA_LOGIN_LEN); strncpy((char*)disconnSyn8->type, "DISCONN_SYN", IA_MAX_TYPE_LEN); strncpy((char*)disconnSyn8->login, login.c_str(), IA_LOGIN_LEN); -return disconnSyn8->len; +return sizeof(DISCONN_SYN_8); } //--------------------------------------------------------------------------- int IA_CLIENT_PROT::Prepare_DISCONN_ACK_8(char * buffer) { disconnAck8 = (DISCONN_ACK_8*)buffer; +assert(Min8(sizeof(DISCONN_ACK_8)) == sizeof(DISCONN_ACK_8) && "DISCONN_ACK_8 is not aligned to 8 bytes"); + +disconnAck8->len = Min8(sizeof(DISCONN_ACK_8)); +disconnAck8->rnd = rnd + 1; + #ifdef ARCH_BE SwapBytes(disconnAck8->len); SwapBytes(disconnAck8->rnd); #endif -assert(Min8(sizeof(DISCONN_ACK_8)) == sizeof(DISCONN_ACK_8) && "DISCONN_ACK_8 is not aligned to 8 bytes"); - -disconnAck8->len = Min8(sizeof(DISCONN_ACK_8)); -disconnAck8->rnd = rnd + 1; strncpy((char*)disconnAck8->loginS, login.c_str(), IA_LOGIN_LEN); strncpy((char*)disconnAck8->type, "DISCONN_ACK", IA_MAX_TYPE_LEN); -return disconnAck8->len; +return Min8(sizeof(DISCONN_ACK_8)); } //--------------------------------------------------------------------------- void IA_CLIENT_PROT::SetStatusChangedCb(tpStatusChangedCb p, void * data)