]> git.stg.codes - stg.git/commitdiff
Added local binding.
authorMaxim Mamontov <faust.madf@gmail.com>
Fri, 30 May 2014 07:55:15 +0000 (10:55 +0300)
committerMaxim Mamontov <faust.madf@gmail.com>
Fri, 30 May 2014 07:55:15 +0000 (10:55 +0300)
12 files changed:
projects/sgconf/admins.cpp
projects/sgconf/config.h
projects/sgconf/corps.cpp
projects/sgconf/main.cpp
projects/sgconf/services.cpp
projects/sgconf/tariffs.cpp
projects/sgconf/users.cpp
projects/sgconf/xml.cpp
stglibs/srvconf.lib/include/stg/servconf.h
stglibs/srvconf.lib/netunit.cpp
stglibs/srvconf.lib/netunit.h
stglibs/srvconf.lib/servconf.cpp

index 7161e1efd421664ac6aa9e65fae140892af7006e..c16e6e2b2d981dfb1897e585c8fa209b00f6be25 100644 (file)
@@ -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 <GetAdmin login="..."/>.
@@ -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;
index 424ca519e79dba44ae56d4b464753bd4173e3844..e52111e3fcd9eac231bd54ed335974609469aede 100644 (file)
@@ -35,6 +35,8 @@ struct CONFIG
     RESETABLE<std::string> configFile;
     RESETABLE<std::string> server;
     RESETABLE<uint16_t> port;
+    RESETABLE<std::string> localAddress;
+    RESETABLE<uint16_t> localPort;
     RESETABLE<std::string> userName;
     RESETABLE<std::string> 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())
index f079acfc4ef588791681abf45dcdb306b33f484a..4bd436dd2f56676e09e165fb4c78a2563d04b8ba 100644 (file)
@@ -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;
index 0715b7b19ce9bcc6fc793e9b754ae506faaacabd..3a627aef3444db56f43357d6dcdca50d6234b159 100644 (file)
@@ -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"), "<address>"), "\t\thost to connect")
       .Add("p", "port", SGCONF::MakeParamAction(config.port, uint16_t(5555), "<port>"), "\t\tport to connect")
+      .Add("local-address", SGCONF::MakeParamAction(config.localAddress, std::string(""), "<address>"), "\t\tlocal address to bind")
+      .Add("local-port", SGCONF::MakeParamAction(config.localPort, uint16_t(0), "<port>"), "\t\tlocal port to bind")
       .Add("u", "username", SGCONF::MakeParamAction(config.userName, std::string("admin"), "<username>"), "\tadministrative login")
       .Add("w", "userpass", SGCONF::MakeParamAction(config.userPass, "<password>"), "\tpassword for the administrative login")
       .Add("a", "address", SGCONF::MakeParamAction(config, "<connection string>"), "connection params as a single string in format: <login>:<password>@<host>:<port>");
index 5c63f7e40f206987769fd9f88d0f64328802f954..22a640130ec01c5acbd9049c7bddd051c4799961 100644 (file)
@@ -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;
index a108920f86a2a70dd2486687c654f70c8528e496..663536fb78c3174c5cfd31bb12328e8f961becc1 100644 (file)
@@ -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 <GetTariff name="..."/>.
@@ -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;
index 7a20160b9e3592dc48baffcc38a299cdf816c103..ca555a1140be3fb61afc4f34a1d11cf7b04d6052 100644 (file)
@@ -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;
index c54fcd02bbd17fb10878da556a956131462a18b2..abf2ccc62e96f8643a9ff808d5a344c7d3964bd7 100644 (file)
@@ -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;
index 467671db19e3f2582739f4e8a67ded41aaa1106e..cd37e49e44b984ae84317c17ac3eeb8bc99baf88 100644 (file)
@@ -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);
index 164823d8395d42d41f81f11a728dfdba5c34c958..a8b36e5715514dad3b3f3f60af23b8cb5dc9da09 100644 (file)
@@ -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));
 
index ce9f8f1c9cadc4ec8f53d6467964b56d31bab967..b6584ee57b46e68fdf75253b91e1202eb2304c04 100644 (file)
@@ -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; }
 
index 0f91a563033c52ba650204b356f05afafa8a5449..4f74ae8f7d4d0b80b6ae24e73c399522bdc085eb 100644 (file)
@@ -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);
 }