From 49ac42e64c982c16ca4421a50d15f36574ca0c10 Mon Sep 17 00:00:00 2001 From: Maxim Mamontov Date: Fri, 30 May 2014 10:55:15 +0300 Subject: [PATCH 1/1] Added local binding. --- projects/sgconf/admins.cpp | 10 +++++ projects/sgconf/config.h | 10 +++++ projects/sgconf/corps.cpp | 10 +++++ projects/sgconf/main.cpp | 2 + projects/sgconf/services.cpp | 10 +++++ projects/sgconf/tariffs.cpp | 10 +++++ projects/sgconf/users.cpp | 14 +++++++ projects/sgconf/xml.cpp | 2 + stglibs/srvconf.lib/include/stg/servconf.h | 3 ++ stglibs/srvconf.lib/netunit.cpp | 49 ++++++++++++++++++++++ stglibs/srvconf.lib/netunit.h | 3 ++ stglibs/srvconf.lib/servconf.cpp | 20 ++++++++- 12 files changed, 142 insertions(+), 1 deletion(-) diff --git a/projects/sgconf/admins.cpp b/projects/sgconf/admins.cpp index 7161e1ef..c16e6e2b 100644 --- a/projects/sgconf/admins.cpp +++ b/projects/sgconf/admins.cpp @@ -120,6 +120,8 @@ bool GetAdminsFunction(const SGCONF::CONFIG & config, { STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); return proto.GetAdmins(GetAdminsCallback, NULL) == STG::st_ok; @@ -131,6 +133,8 @@ bool GetAdminFunction(const SGCONF::CONFIG & config, { STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); // STG currently doesn't support . @@ -145,6 +149,8 @@ bool DelAdminFunction(const SGCONF::CONFIG & config, { STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); return proto.DelAdmin(arg, SimpleCallback, NULL) == STG::st_ok; @@ -160,6 +166,8 @@ SGCONF::MaybeSet(options, "priv", conf.priv, ConvPriv); SGCONF::MaybeSet(options, "password", conf.password); STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); return proto.AddAdmin(arg, conf, SimpleCallback, NULL) == STG::st_ok; @@ -175,6 +183,8 @@ SGCONF::MaybeSet(options, "priv", conf.priv, ConvPriv); SGCONF::MaybeSet(options, "password", conf.password); STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); return proto.ChgAdmin(conf, SimpleCallback, NULL) == STG::st_ok; diff --git a/projects/sgconf/config.h b/projects/sgconf/config.h index 424ca519..e52111e3 100644 --- a/projects/sgconf/config.h +++ b/projects/sgconf/config.h @@ -35,6 +35,8 @@ struct CONFIG RESETABLE configFile; RESETABLE server; RESETABLE port; + RESETABLE localAddress; + RESETABLE localPort; RESETABLE userName; RESETABLE userPass; @@ -46,6 +48,10 @@ struct CONFIG server = rhs.server; if (!rhs.port.empty()) port = rhs.port; + if (!rhs.localAddress.empty()) + localAddress = rhs.localAddress; + if (!rhs.localPort.empty()) + localPort = rhs.localPort; if (!rhs.userName.empty()) userName = rhs.userName; if (!rhs.userPass.empty()) @@ -62,6 +68,10 @@ struct CONFIG res += " server: '" + server.data() + "',"; if (!port.empty()) res += " port: " + x2str(port.data()) + ","; + if (!localAddress.empty()) + res += " local address: '" + localAddress.data() + "',"; + if (!localPort.empty()) + res += " local port: " + x2str(localPort.data()) + ","; if (!userName.empty()) res += " userName: '" + userName.data() + "',"; if (!userPass.empty()) diff --git a/projects/sgconf/corps.cpp b/projects/sgconf/corps.cpp index f079acfc..4bd436dd 100644 --- a/projects/sgconf/corps.cpp +++ b/projects/sgconf/corps.cpp @@ -83,6 +83,8 @@ bool GetCorpsFunction(const SGCONF::CONFIG & config, { STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); return proto.GetCorporations(GetCorpsCallback, NULL) == STG::st_ok; @@ -94,6 +96,8 @@ bool GetCorpFunction(const SGCONF::CONFIG & config, { STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); return proto.GetCorp(arg, GetCorpCallback, NULL) == STG::st_ok; @@ -105,6 +109,8 @@ bool DelCorpFunction(const SGCONF::CONFIG & config, { STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); return proto.DelCorp(arg, SimpleCallback, NULL) == STG::st_ok; @@ -119,6 +125,8 @@ conf.name = arg; SGCONF::MaybeSet(options, "cash", conf.cash); STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); return proto.AddCorp(arg, conf, SimpleCallback, NULL) == STG::st_ok; @@ -133,6 +141,8 @@ conf.name = arg; SGCONF::MaybeSet(options, "cash", conf.cash); STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); return proto.ChgCorp(conf, SimpleCallback, NULL) == STG::st_ok; diff --git a/projects/sgconf/main.cpp b/projects/sgconf/main.cpp index 0715b7b1..3a627aef 100644 --- a/projects/sgconf/main.cpp +++ b/projects/sgconf/main.cpp @@ -251,6 +251,8 @@ blocks.Add("General options") SGCONF::OPTION_BLOCK & block = blocks.Add("Connection options") .Add("s", "server", SGCONF::MakeParamAction(config.server, std::string("localhost"), "
"), "\t\thost to connect") .Add("p", "port", SGCONF::MakeParamAction(config.port, uint16_t(5555), ""), "\t\tport to connect") + .Add("local-address", SGCONF::MakeParamAction(config.localAddress, std::string(""), "
"), "\t\tlocal address to bind") + .Add("local-port", SGCONF::MakeParamAction(config.localPort, uint16_t(0), ""), "\t\tlocal port to bind") .Add("u", "username", SGCONF::MakeParamAction(config.userName, std::string("admin"), ""), "\tadministrative login") .Add("w", "userpass", SGCONF::MakeParamAction(config.userPass, ""), "\tpassword for the administrative login") .Add("a", "address", SGCONF::MakeParamAction(config, ""), "connection params as a single string in format: :@:"); diff --git a/projects/sgconf/services.cpp b/projects/sgconf/services.cpp index 5c63f7e4..22a64013 100644 --- a/projects/sgconf/services.cpp +++ b/projects/sgconf/services.cpp @@ -87,6 +87,8 @@ bool GetServicesFunction(const SGCONF::CONFIG & config, { STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); return proto.GetServices(GetServicesCallback, NULL) == STG::st_ok; @@ -98,6 +100,8 @@ bool GetServiceFunction(const SGCONF::CONFIG & config, { STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); return proto.GetService(arg, GetServiceCallback, NULL) == STG::st_ok; @@ -109,6 +113,8 @@ bool DelServiceFunction(const SGCONF::CONFIG & config, { STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); return proto.DelService(arg, SimpleCallback, NULL) == STG::st_ok; @@ -125,6 +131,8 @@ SGCONF::MaybeSet(options, "pay-day", conf.payDay); SGCONF::MaybeSet(options, "comment", conf.comment); STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); return proto.AddService(arg, conf, SimpleCallback, NULL) == STG::st_ok; @@ -141,6 +149,8 @@ SGCONF::MaybeSet(options, "pay-day", conf.payDay); SGCONF::MaybeSet(options, "comment", conf.comment); STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); return proto.ChgService(conf, SimpleCallback, NULL) == STG::st_ok; diff --git a/projects/sgconf/tariffs.cpp b/projects/sgconf/tariffs.cpp index a108920f..663536fb 100644 --- a/projects/sgconf/tariffs.cpp +++ b/projects/sgconf/tariffs.cpp @@ -290,6 +290,8 @@ bool GetTariffsFunction(const SGCONF::CONFIG & config, { STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); return proto.GetTariffs(GetTariffsCallback, NULL) == STG::st_ok; @@ -301,6 +303,8 @@ bool GetTariffFunction(const SGCONF::CONFIG & config, { STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); // STG currently doesn't support . @@ -315,6 +319,8 @@ bool DelTariffFunction(const SGCONF::CONFIG & config, { STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); return proto.DelTariff(arg, SimpleCallback, NULL) == STG::st_ok; @@ -346,6 +352,8 @@ for (size_t i = 0; i < conf.dirPrice.size(); ++i) } STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); return proto.AddTariff(arg, conf, SimpleCallback, NULL) == STG::st_ok; @@ -377,6 +385,8 @@ for (size_t i = 0; i < conf.dirPrice.size(); ++i) } STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); return proto.ChgTariff(conf, SimpleCallback, NULL) == STG::st_ok; diff --git a/projects/sgconf/users.cpp b/projects/sgconf/users.cpp index 7a20160b..ca555a11 100644 --- a/projects/sgconf/users.cpp +++ b/projects/sgconf/users.cpp @@ -274,6 +274,8 @@ bool GetUsersFunction(const SGCONF::CONFIG & config, { STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); return proto.GetUsers(GetUsersCallback, NULL) == STG::st_ok; @@ -285,6 +287,8 @@ bool GetUserFunction(const SGCONF::CONFIG & config, { STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); return proto.GetUser(arg, GetUserCallback, NULL) == STG::st_ok; @@ -296,6 +300,8 @@ bool DelUserFunction(const SGCONF::CONFIG & config, { STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); return proto.DelUser(arg, SimpleCallback, NULL) == STG::st_ok; @@ -332,6 +338,8 @@ SGCONF::MaybeSet(options, "session-traffic", stat, ConvSessionTraff); SGCONF::MaybeSet(options, "month-traffic", stat, ConvMonthTraff); STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); return proto.AddUser(arg, conf, stat, SimpleCallback, NULL) == STG::st_ok; @@ -369,6 +377,8 @@ SGCONF::MaybeSet(options, "session-traffic", stat, ConvSessionTraff); SGCONF::MaybeSet(options, "month-traffic", stat, ConvMonthTraff); STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); return proto.ChgUser(arg, conf, stat, SimpleCallback, NULL) == STG::st_ok; @@ -383,6 +393,8 @@ if (it == options.end()) throw SGCONF::ACTION::ERROR("Password is not specified."); STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); return proto.CheckUser(arg, it->second, SimpleCallback, NULL) == STG::st_ok; @@ -405,6 +417,8 @@ if (it == options.end()) std::string text = it->second; STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); return proto.SendMessage(logins, text, SimpleCallback, NULL) == STG::st_ok; diff --git a/projects/sgconf/xml.cpp b/projects/sgconf/xml.cpp index c54fcd02..abf2ccc6 100644 --- a/projects/sgconf/xml.cpp +++ b/projects/sgconf/xml.cpp @@ -89,6 +89,8 @@ bool RawXMLFunction(const SGCONF::CONFIG & config, { STG::SERVCONF proto(config.server.data(), config.port.data(), + config.localAddress.data(), + config.localPort.data(), config.userName.data(), config.userPass.data()); return proto.RawXML(arg, RawXMLCallback, NULL) == STG::st_ok; diff --git a/stglibs/srvconf.lib/include/stg/servconf.h b/stglibs/srvconf.lib/include/stg/servconf.h index 467671db..cd37e49e 100644 --- a/stglibs/srvconf.lib/include/stg/servconf.h +++ b/stglibs/srvconf.lib/include/stg/servconf.h @@ -43,6 +43,9 @@ class SERVCONF public: SERVCONF(const std::string & server, uint16_t port, const std::string & login, const std::string & password); + SERVCONF(const std::string & server, uint16_t port, + const std::string & localAddress, uint16_t localPort, + const std::string & login, const std::string & password); ~SERVCONF(); int ServerInfo(SERVER_INFO::CALLBACK f, void * data); diff --git a/stglibs/srvconf.lib/netunit.cpp b/stglibs/srvconf.lib/netunit.cpp index 164823d8..a8b36e57 100644 --- a/stglibs/srvconf.lib/netunit.cpp +++ b/stglibs/srvconf.lib/netunit.cpp @@ -53,6 +53,7 @@ const std::string::size_type MAX_XML_CHUNK_LENGTH = 2048; #define RECV_DATA_ANSWER_ERROR "Recv data answer error!" #define UNKNOWN_ERROR "Unknown error!" #define CONNECT_FAILED "Connect failed!" +#define BIND_FAILED "Bind failed!" #define INCORRECT_LOGIN "Incorrect login!" #define INCORRECT_HEADER "Incorrect header!" #define SEND_LOGIN_ERROR "Send login error!" @@ -73,6 +74,19 @@ NETTRANSACT::NETTRANSACT(const std::string & s, uint16_t p, { } //--------------------------------------------------------------------------- +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), + outerSocket(-1) +{ +} +//--------------------------------------------------------------------------- int NETTRANSACT::Connect() { outerSocket = socket(PF_INET, SOCK_STREAM, 0); @@ -82,6 +96,41 @@ if (outerSocket < 0) 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 = "DNS error.\nCan 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(outerSocket, (struct sockaddr *)&localAddr, sizeof(localAddr)) < 0) + { + errorMsg = BIND_FAILED; + close(outerSocket); + return st_conn_fail; + } + } + struct sockaddr_in outerAddr; memset(&outerAddr, 0, sizeof(outerAddr)); diff --git a/stglibs/srvconf.lib/netunit.h b/stglibs/srvconf.lib/netunit.h index ce9f8f1c..b6584ee5 100644 --- a/stglibs/srvconf.lib/netunit.h +++ b/stglibs/srvconf.lib/netunit.h @@ -32,6 +32,9 @@ public: NETTRANSACT(const std::string & server, uint16_t port, const std::string & login, const std::string & password); + NETTRANSACT(const std::string & server, uint16_t port, + const std::string & localAddress, uint16_t localPort, + const std::string & login, const std::string & password); int Transact(const std::string & request, CALLBACK f, void * data); const std::string & GetError() const { return errorMsg; } diff --git a/stglibs/srvconf.lib/servconf.cpp b/stglibs/srvconf.lib/servconf.cpp index 0f91a563..4f74ae8f 100644 --- a/stglibs/srvconf.lib/servconf.cpp +++ b/stglibs/srvconf.lib/servconf.cpp @@ -60,6 +60,9 @@ class SERVCONF::IMPL public: IMPL(const std::string & server, uint16_t port, const std::string & login, const std::string & password); + IMPL(const std::string & server, uint16_t port, + const std::string & localAddress, uint16_t localPort, + const std::string & login, const std::string & password); ~IMPL() { XML_ParserFree(parser); } const std::string & GetStrError() const; @@ -121,6 +124,13 @@ SERVCONF::SERVCONF(const std::string & server, uint16_t port, { } +SERVCONF::SERVCONF(const std::string & server, uint16_t port, + const std::string & localAddress, uint16_t localPort, + const std::string & login, const std::string & password) + : pImpl(new IMPL(server, port, localAddress, localPort, login, password)) +{ +} + SERVCONF::~SERVCONF() { delete pImpl; @@ -323,7 +333,15 @@ return pImpl->GetStrError(); //----------------------------------------------------------------------------- SERVCONF::IMPL::IMPL(const std::string & server, uint16_t port, const std::string & login, const std::string & password) - : nt( server, port, login, password ) + : nt(server, port, login, password) +{ +parser = XML_ParserCreate(NULL); +} +//----------------------------------------------------------------------------- +SERVCONF::IMPL::IMPL(const std::string & server, uint16_t port, + const std::string & localAddress, uint16_t localPort, + const std::string & login, const std::string & password) + : nt(server, port, localAddress, localPort, login, password) { parser = XML_ParserCreate(NULL); } -- 2.44.2