X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/0d5bff91a33dc190351adc0010f8218c81423799..refs/heads/ticket37:/stglibs/srvconf.lib/netunit.cpp?ds=sidebyside diff --git a/stglibs/srvconf.lib/netunit.cpp b/stglibs/srvconf.lib/netunit.cpp index 65151587..61dc5c69 100644 --- a/stglibs/srvconf.lib/netunit.cpp +++ b/stglibs/srvconf.lib/netunit.cpp @@ -18,213 +18,159 @@ * Author : Boris Mikhailenko */ -#include "netunit.h" - -#include "stg/servconf_types.h" -#include "stg/common.h" -#include "stg/blowfish.h" -#include "stg/bfstream.h" - -#include // std::min - -#include -#include -#include + /* + $Revision: 1.6 $ + $Date: 2009/02/06 10:25:54 $ + $Author: faust $ + */ +//--------------------------------------------------------------------------- #include #include #include -#include -#include -#include - -const char STG_HEADER[] = "SG04"; -const char OK_HEADER[] = "OKHD"; -const char ERR_HEADER[] = "ERHD"; -const char OK_LOGIN[] = "OKLG"; -const char ERR_LOGIN[] = "ERLG"; -const char OK_LOGINS[] = "OKLS"; -const char ERR_LOGINS[] = "ERLS"; - -using namespace STG; - -namespace -{ - -struct ReadState -{ - bool final; - NETTRANSACT::CALLBACK callback; - void * callbackData; - NETTRANSACT * nt; -}; +#include +#include -} +#include "stg/netunit.h" +#include "stg/common.h" //--------------------------------------------------------------------------- -const char SEND_DATA_ERROR[] = "Error sending data."; -const char RECV_DATA_ANSWER_ERROR[] = "Error receiving data answer."; -const char UNKNOWN_ERROR[] = "Unknown error"; -const char CONNECT_FAILED[] = "Failed to connect."; -const char BIND_FAILED[] = "Failed to bind."; -const char INCORRECT_LOGIN[] = "Incorrect login."; -const char INCORRECT_HEADER[] = "Incorrect header."; -const char SEND_LOGIN_ERROR[] = "Error sending login."; -const char RECV_LOGIN_ANSWER_ERROR[] = "Error receiving login answer."; -const char CREATE_SOCKET_ERROR[] = "Failed to create socket."; -const char SEND_HEADER_ERROR[] = "Error sending header."; -const char RECV_HEADER_ANSWER_ERROR[] = "Error receiving header answer."; +#define SEND_DATA_ERROR "Send data error!" +#define RECV_DATA_ANSWER_ERROR "Recv data answer error!" +#define UNKNOWN_ERROR "Unknown error!" +#define CONNECT_FAILED "Connect failed!" +#define INCORRECT_LOGIN "Incorrect login!" +#define INCORRECT_HEADER "Incorrect header!" +#define SEND_LOGIN_ERROR "Send login error!" +#define RECV_LOGIN_ANSWER_ERROR "Recv login answer error!" +#define CREATE_SOCKET_ERROR "Create socket failed!" +#define WSASTARTUP_FAILED "WSAStartup failed!" +#define SEND_HEADER_ERROR "Send header error!" +#define RECV_HEADER_ANSWER_ERROR "Recv header answer error!" //--------------------------------------------------------------------------- -NETTRANSACT::NETTRANSACT(const std::string & s, uint16_t p, - const std::string & l, const std::string & pwd) - : server(s), - port(p), - localPort(0), - login(l), - password(pwd), - sock(-1) +NETTRANSACT::NETTRANSACT() + : port(0), + outerSocket(-1), + RxCallBack(NULL), + dataRxCallBack(NULL) { } //--------------------------------------------------------------------------- -NETTRANSACT::NETTRANSACT(const std::string & s, uint16_t p, - const std::string & la, uint16_t lp, - const std::string & l, const std::string & pwd) - : server(s), - port(p), - localAddress(la), - localPort(lp), - login(l), - password(pwd), - sock(-1) -{ -} -//--------------------------------------------------------------------------- -NETTRANSACT::~NETTRANSACT() -{ -Disconnect(); -} -//--------------------------------------------------------------------------- int NETTRANSACT::Connect() { -sock = socket(PF_INET, SOCK_STREAM, 0); -if (sock < 0) +int ret; + +outerSocket = socket(PF_INET, SOCK_STREAM, 0); +if (outerSocket < 0) { errorMsg = CREATE_SOCKET_ERROR; return st_conn_fail; } -if (!localAddress.empty()) - { - if (localPort == 0) - localPort = port; - - unsigned long ip = inet_addr(localAddress.c_str()); - - if (ip == INADDR_NONE) - { - struct hostent * phe = gethostbyname(localAddress.c_str()); - if (phe == NULL) - { - errorMsg = "Can not reslove '" + localAddress + "'"; - return st_dns_err; - } - - struct hostent he; - memcpy(&he, phe, sizeof(he)); - ip = *((long *)he.h_addr_list[0]); - } - - struct sockaddr_in localAddr; - memset(&localAddr, 0, sizeof(localAddr)); - localAddr.sin_family = AF_INET; - localAddr.sin_port = htons(localPort); - localAddr.sin_addr.s_addr = ip; - - if (bind(sock, (struct sockaddr *)&localAddr, sizeof(localAddr)) < 0) - { - errorMsg = BIND_FAILED; - return st_conn_fail; - } - } - struct sockaddr_in outerAddr; memset(&outerAddr, 0, sizeof(outerAddr)); -unsigned long ip = inet_addr(server.c_str()); +struct hostent he; +struct hostent * phe; + +unsigned long ip; +ip = inet_addr(server.c_str()); if (ip == INADDR_NONE) { - struct hostent * phe = gethostbyname(server.c_str()); + phe = gethostbyname(server.c_str()); if (phe == NULL) { - errorMsg = "Can not reslove '" + server + "'"; + errorMsg = "DNS error.\nCan not reslove " + server; return st_dns_err; } - struct hostent he; memcpy(&he, phe, sizeof(he)); - ip = *((long *)he.h_addr_list[0]); + ip = *((long*)he.h_addr_list[0]); } - outerAddr.sin_family = AF_INET; outerAddr.sin_port = htons(port); outerAddr.sin_addr.s_addr = ip; -if (connect(sock, (struct sockaddr *)&outerAddr, sizeof(outerAddr)) < 0) +ret = connect(outerSocket, (struct sockaddr*)&outerAddr, sizeof(outerAddr)); + +if (ret < 0) { errorMsg = CONNECT_FAILED; + close(outerSocket); return st_conn_fail; } - return st_ok; } //--------------------------------------------------------------------------- -void NETTRANSACT::Disconnect() +int NETTRANSACT::Disconnect() { -if (sock != -1) - { - shutdown(sock, SHUT_RDWR); - close(sock); - sock = -1; - } +close(outerSocket); +return 0; } //--------------------------------------------------------------------------- -int NETTRANSACT::Transact(const std::string & request, CALLBACK callback, void * data) +int NETTRANSACT::Transact(const char * data) { int ret; if ((ret = TxHeader()) != st_ok) + { + Disconnect(); return ret; + } if ((ret = RxHeaderAnswer()) != st_ok) + { + Disconnect(); return ret; + } if ((ret = TxLogin()) != st_ok) + { + Disconnect(); return ret; + } if ((ret = RxLoginAnswer()) != st_ok) + { + Disconnect(); return ret; + } if ((ret = TxLoginS()) != st_ok) + { + Disconnect(); return ret; + } if ((ret = RxLoginSAnswer()) != st_ok) + { + Disconnect(); return ret; + } -if ((ret = TxData(request)) != st_ok) +if ((ret = TxData(data)) != st_ok) + { + Disconnect(); return ret; + } -if ((ret = RxDataAnswer(callback, data)) != st_ok) +if ((ret = RxDataAnswer()) != st_ok) + { + Disconnect(); return ret; + } return st_ok; } //--------------------------------------------------------------------------- int NETTRANSACT::TxHeader() { -if (!WriteAll(sock, STG_HEADER, strlen(STG_HEADER))) +int ret; +ret = send(outerSocket, STG_HEADER, strlen(STG_HEADER), 0); +if (ret <= 0) { errorMsg = SEND_HEADER_ERROR; return st_send_fail; @@ -235,36 +181,45 @@ return st_ok; //--------------------------------------------------------------------------- int NETTRANSACT::RxHeaderAnswer() { -char buffer[sizeof(STG_HEADER) + 1]; +char buffer[sizeof(STG_HEADER)+1]; +int ret; -if (!ReadAll(sock, buffer, strlen(OK_HEADER))) +ret = recv(outerSocket, buffer, strlen(OK_HEADER), 0); +if (ret <= 0) { errorMsg = RECV_HEADER_ANSWER_ERROR; return st_recv_fail; } if (strncmp(OK_HEADER, buffer, strlen(OK_HEADER)) == 0) - return st_ok; - -if (strncmp(ERR_HEADER, buffer, strlen(ERR_HEADER)) == 0) { - errorMsg = INCORRECT_HEADER; - return st_header_err; + return st_ok; } else { - errorMsg = UNKNOWN_ERROR; - return st_unknown_err; + if (strncmp(ERR_HEADER, buffer, strlen(ERR_HEADER)) == 0) + { + errorMsg = INCORRECT_HEADER; + return st_header_err; + } + else + { + errorMsg = UNKNOWN_ERROR; + return st_unknown_err; + } } } //--------------------------------------------------------------------------- int NETTRANSACT::TxLogin() { -char loginZ[ADM_LOGIN_LEN + 1]; -memset(loginZ, 0, ADM_LOGIN_LEN + 1); +char loginZ[ADM_LOGIN_LEN]; +int ret; + +memset(loginZ, 0, ADM_LOGIN_LEN); strncpy(loginZ, login.c_str(), ADM_LOGIN_LEN); +ret = send(outerSocket, loginZ, ADM_LOGIN_LEN, 0); -if (!WriteAll(sock, loginZ, ADM_LOGIN_LEN)) +if (ret <= 0) { errorMsg = SEND_LOGIN_ERROR; return st_send_fail; @@ -275,130 +230,175 @@ return st_ok; //--------------------------------------------------------------------------- int NETTRANSACT::RxLoginAnswer() { -char buffer[sizeof(OK_LOGIN) + 1]; +char buffer[sizeof(OK_LOGIN)+1]; +int ret; -if (!ReadAll(sock, buffer, strlen(OK_LOGIN))) +ret = recv(outerSocket, buffer, strlen(OK_LOGIN), 0); +if (ret <= 0) { errorMsg = RECV_LOGIN_ANSWER_ERROR; return st_recv_fail; } if (strncmp(OK_LOGIN, buffer, strlen(OK_LOGIN)) == 0) - return st_ok; - -if (strncmp(ERR_LOGIN, buffer, strlen(ERR_LOGIN)) == 0) { - errorMsg = INCORRECT_LOGIN; - return st_login_err; + return st_ok; } else { - errorMsg = UNKNOWN_ERROR; - return st_unknown_err; + if (strncmp(ERR_LOGIN, buffer, strlen(ERR_LOGIN)) == 0) + { + errorMsg = INCORRECT_LOGIN; + return st_login_err; + } + else + { + errorMsg = UNKNOWN_ERROR; + return st_unknown_err; + } } } //--------------------------------------------------------------------------- int NETTRANSACT::TxLoginS() { -char loginZ[ADM_LOGIN_LEN + 1]; -memset(loginZ, 0, ADM_LOGIN_LEN + 1); +char loginZ[ADM_LOGIN_LEN]; +memset(loginZ, 0, ADM_LOGIN_LEN); BLOWFISH_CTX ctx; InitContext(password.c_str(), PASSWD_LEN, &ctx); -EncryptString(loginZ, login.c_str(), std::min(login.length() + 1, ADM_LOGIN_LEN), &ctx); -if (!WriteAll(sock, loginZ, ADM_LOGIN_LEN)) +EncryptString(loginZ, login.c_str(), std::min(login.length() + 1, ADM_LOGIN_LEN), &ctx); +if (send(outerSocket, loginZ, ADM_LOGIN_LEN, 0) <= 0) { errorMsg = SEND_LOGIN_ERROR; return st_send_fail; } - return st_ok; } //--------------------------------------------------------------------------- int NETTRANSACT::RxLoginSAnswer() { -char buffer[sizeof(OK_LOGINS) + 1]; +char buffer[sizeof(OK_LOGINS)+1]; +int ret; -if (!ReadAll(sock, buffer, strlen(OK_LOGINS))) +ret = recv(outerSocket, buffer, strlen(OK_LOGINS), 0); +if (ret <= 0) { errorMsg = RECV_LOGIN_ANSWER_ERROR; return st_recv_fail; } if (strncmp(OK_LOGINS, buffer, strlen(OK_LOGINS)) == 0) - return st_ok; - -if (strncmp(ERR_LOGINS, buffer, strlen(ERR_LOGINS)) == 0) { - errorMsg = INCORRECT_LOGIN; - return st_logins_err; + return st_ok; } else { - errorMsg = UNKNOWN_ERROR; - return st_unknown_err; + if (strncmp(ERR_LOGINS, buffer, strlen(ERR_LOGINS)) == 0) + { + errorMsg = INCORRECT_LOGIN; + return st_logins_err; + } + else + { + errorMsg = UNKNOWN_ERROR; + return st_unknown_err; + } } } //--------------------------------------------------------------------------- -int NETTRANSACT::TxData(const std::string & text) +int NETTRANSACT::TxData(const char * text) { -STG::ENCRYPT_STREAM stream(password, TxCrypto, this); -stream.Put(text.c_str(), text.length() + 1, true); -if (!stream.IsOk()) +BLOWFISH_CTX ctx; +InitContext(password.c_str(), PASSWD_LEN, &ctx); +size_t length = strlen(text); +char buffer[length + 9]; +memset(buffer, 0, sizeof(buffer)); +EncryptString(buffer, text, length + 1, &ctx); +if (send(outerSocket, buffer, sizeof(buffer), 0) <= 0) { errorMsg = SEND_DATA_ERROR; return st_send_fail; } - return st_ok; } //--------------------------------------------------------------------------- -int NETTRANSACT::RxDataAnswer(CALLBACK callback, void * data) +int NETTRANSACT::RxDataAnswer() { -ReadState state = {false, callback, data, this}; -STG::DECRYPT_STREAM stream(password, RxCrypto, &state); -while (!state.final) +int n = 0; +int ret; +char bufferS[ENC_MSG_LEN]; +char buffer[ENC_MSG_LEN + 1]; + +BLOWFISH_CTX ctx; +InitContext(password.c_str(), PASSWD_LEN, &ctx); + +while (1) { - char buffer[1024]; - ssize_t res = read(sock, buffer, sizeof(buffer)); - if (res < 0) + ret = recv(outerSocket, &bufferS[n++], 1, 0); + if (ret <= 0) { + close(outerSocket); errorMsg = RECV_DATA_ANSWER_ERROR; return st_recv_fail; } - stream.Put(buffer, res, res == 0); - if (!stream.IsOk()) - return st_xml_parse_error; - } -return st_ok; + if (n == ENC_MSG_LEN) + { + n = 0; + DecryptBlock(buffer, bufferS, &ctx); + buffer[ENC_MSG_LEN] = 0; + + answerList.push_back(buffer); + + for (int j = 0; j < ENC_MSG_LEN; j++) + { + if (buffer[j] == 0) + { + if (RxCallBack) + if (st_ok != RxCallBack(dataRxCallBack, &answerList)) + { + return st_xml_parse_error; + } + return st_ok; + } + } + } + } } //--------------------------------------------------------------------------- -bool NETTRANSACT::TxCrypto(const void * block, size_t size, void * data) +void NETTRANSACT::SetLogin(const char * l) { -assert(data != NULL); -NETTRANSACT & nt = *static_cast(data); -if (!WriteAll(nt.sock, block, size)) - return false; -return true; +login = l; } //--------------------------------------------------------------------------- -bool NETTRANSACT::RxCrypto(const void * block, size_t size, void * data) +void NETTRANSACT::SetPassword(const char * p) { -assert(data != NULL); -ReadState & state = *static_cast(data); - -const char * buffer = static_cast(block); -for (size_t pos = 0; pos < size; ++pos) - if (buffer[pos] == 0) - { - state.final = true; - size = pos; // Adjust string size - } - -if (state.callback) - if (!state.callback(std::string(buffer, size), state.final, state.callbackData)) - return false; - -return true; +password = p; } +//--------------------------------------------------------------------------- +void NETTRANSACT::SetServer(const char * serverName) +{ +server = serverName; +} +//--------------------------------------------------------------------------- +void NETTRANSACT::SetServerPort(short unsigned p) +{ +port = p; +} +//--------------------------------------------------------------------------- +void NETTRANSACT::SetRxCallback(void * data, RxCallback_t cb) +{ +RxCallBack = cb; +dataRxCallBack = data; +} +//--------------------------------------------------------------------------- +const std::string & NETTRANSACT::GetError() const +{ +return errorMsg; +} +//--------------------------------------------------------------------------- +void NETTRANSACT::Reset() +{ +answerList.clear(); +} +//---------------------------------------------------------------------------