diff --git a/apps/xmlrpc2di/XMLRPC2DI.cpp b/apps/xmlrpc2di/XMLRPC2DI.cpp index 4e4c9897..0d471953 100644 --- a/apps/xmlrpc2di/XMLRPC2DI.cpp +++ b/apps/xmlrpc2di/XMLRPC2DI.cpp @@ -122,6 +122,11 @@ int XMLRPC2DI::load() { return 0; } + string bind_ip = cfg.getParameter("server_ip"); + if (bind_ip.empty()) { + DBG("binding on ANY interface\n"); + } + string conf_xmlrpc_port = cfg.getParameter("xmlrpc_port",XMLRPC_PORT); if (conf_xmlrpc_port.empty()) { ERROR("configuration: xmlrpc_port must be defined!\n"); @@ -150,7 +155,7 @@ int XMLRPC2DI::load() { DBG("XMLRPC Server: %snabling builtin method 'di'.\n", export_di?"E":"Not e"); - server = new XMLRPC2DIServer(XMLRPCPort, export_di, direct_export, s); + server = new XMLRPC2DIServer(XMLRPCPort, bind_ip, export_di, direct_export, s); server->start(); return 0; } @@ -314,11 +319,13 @@ void XMLRPC2DI::invoke(const string& method, // XMLRPC server functions -XMLRPC2DIServer::XMLRPC2DIServer(unsigned int port, +XMLRPC2DIServer::XMLRPC2DIServer(unsigned int port, + const string& bind_ip, bool di_export, string direct_export, XmlRpcServer* s) : port(port), + bind_ip(bind_ip), s(s), // register method 'calls' calls_method(s), @@ -344,7 +351,8 @@ XMLRPC2DIServer::XMLRPC2DIServer(unsigned int port, } DBG("Initialized XMLRPC2DIServer with: \n"); - DBG(" port = %u\n", port); + DBG(" IP = %s port = %u\n", + bind_ip.empty()?"ANY":bind_ip.c_str(), port); } /** register all methods on xmlrpc server listed by the iface @@ -408,7 +416,7 @@ void XMLRPC2DIServer::registerMethods(const std::string& iface) { void XMLRPC2DIServer::run() { DBG("Binding XMLRPC2DIServer to port %u \n", port); - s->bindAndListen(port); + s->bindAndListen(port, bind_ip); DBG("starting XMLRPC2DIServer...\n"); s->work(-1.0); } diff --git a/apps/xmlrpc2di/XMLRPC2DI.h b/apps/xmlrpc2di/XMLRPC2DI.h index 0e26dd31..4d21cc98 100644 --- a/apps/xmlrpc2di/XMLRPC2DI.h +++ b/apps/xmlrpc2di/XMLRPC2DI.h @@ -85,6 +85,8 @@ class XMLRPC2DIServer : public AmThread { XmlRpcServer* s; unsigned int port; + string bind_ip; + XMLRPC2DIServerCallsMethod calls_method; XMLRPC2DIServerSetLoglevelMethod setloglevel_method; XMLRPC2DIServerGetLoglevelMethod getloglevel_method; @@ -92,7 +94,8 @@ class XMLRPC2DIServer : public AmThread { void registerMethods(const std::string& iface); public: - XMLRPC2DIServer(unsigned int port, + XMLRPC2DIServer(unsigned int port, + const string& bind_ip, bool di_export, string direct_export, XmlRpcServer* s); diff --git a/apps/xmlrpc2di/etc/xmlrpc2di.conf b/apps/xmlrpc2di/etc/xmlrpc2di.conf index 5a49aba6..500b9e9f 100644 --- a/apps/xmlrpc2di/etc/xmlrpc2di.conf +++ b/apps/xmlrpc2di/etc/xmlrpc2di.conf @@ -1,7 +1,10 @@ +# server_ip : IP to bind XMLRPC server to +# leave empty for ANY interface +#server_ip=127.0.0.1 + # port to bind XMLRPC server to xmlrpc_port=8090 - # run multi-threaded server? # Default: yes # diff --git a/apps/xmlrpc2di/xmlrpc++/src/XmlRpcServer.cpp b/apps/xmlrpc2di/xmlrpc++/src/XmlRpcServer.cpp index a32604ff..0d8350df 100644 --- a/apps/xmlrpc2di/xmlrpc++/src/XmlRpcServer.cpp +++ b/apps/xmlrpc2di/xmlrpc++/src/XmlRpcServer.cpp @@ -84,7 +84,7 @@ XmlRpcServer::findMethod(const std::string& name) const // Create a socket, bind to the specified port, and // set it in listen mode to make it available for clients. bool -XmlRpcServer::bindAndListen(int port, int backlog /*= 5*/) +XmlRpcServer::bindAndListen(int port, const std::string& bind_ip, int backlog /*= 5*/) { int fd = XmlRpcSocket::socket(); if (fd < 0) @@ -112,7 +112,7 @@ XmlRpcServer::bindAndListen(int port, int backlog /*= 5*/) } // Bind to the specified port on the default interface - if ( ! XmlRpcSocket::bind(fd, port)) + if ( ! XmlRpcSocket::bind(fd, port, bind_ip)) { this->close(); XmlRpcUtil::error("XmlRpcServer::bindAndListen: Could not bind to specified port (%s).", XmlRpcSocket::getErrorMsg().c_str()); diff --git a/apps/xmlrpc2di/xmlrpc++/src/XmlRpcServer.h b/apps/xmlrpc2di/xmlrpc++/src/XmlRpcServer.h index 28b34a50..f57d9b47 100644 --- a/apps/xmlrpc2di/xmlrpc++/src/XmlRpcServer.h +++ b/apps/xmlrpc2di/xmlrpc++/src/XmlRpcServer.h @@ -55,7 +55,8 @@ namespace XmlRpc { //! Create a socket, bind to the specified port, and //! set it in listen mode to make it available for clients. //! @param port The port to bind and listen on (zero to choose an arbitrary port) - bool bindAndListen(int port, int backlog = 5); + //! @param bind_ip The IP to bind and listen on ("" to listen on ANY interface) + bool bindAndListen(int port, const std::string& bind_ip, int backlog = 5); //! Get the port number this server is listening on. int getPort(void) const; diff --git a/apps/xmlrpc2di/xmlrpc++/src/XmlRpcSocket.cpp b/apps/xmlrpc2di/xmlrpc++/src/XmlRpcSocket.cpp index b54a3c74..9aa2a258 100644 --- a/apps/xmlrpc2di/xmlrpc++/src/XmlRpcSocket.cpp +++ b/apps/xmlrpc2di/xmlrpc++/src/XmlRpcSocket.cpp @@ -25,6 +25,8 @@ extern "C" { # include # include # include + +#include } #endif // _WINDOWS @@ -112,12 +114,21 @@ XmlRpcSocket::setReuseAddr(int fd) // Bind to a specified port bool -XmlRpcSocket::bind(int fd, int port) +XmlRpcSocket::bind(int fd, int port, const std::string& bind_ip) { struct sockaddr_in saddr; memset(&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; - saddr.sin_addr.s_addr = htonl(INADDR_ANY); + if (bind_ip.empty()) { + saddr.sin_addr.s_addr = htonl(INADDR_ANY); + } else { + if(inet_aton(bind_ip.c_str(),&((struct sockaddr_in*)(&saddr))->sin_addr)<0){ + XmlRpcUtil::log(2, "XmlRpcSocket::bind: inet_aton: %s.", + strerror(errno)); + return -1; + } + } + saddr.sin_port = htons((u_short) port); return (::bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) == 0); } diff --git a/apps/xmlrpc2di/xmlrpc++/src/XmlRpcSocket.h b/apps/xmlrpc2di/xmlrpc++/src/XmlRpcSocket.h index 115d3e0f..bf4a4865 100644 --- a/apps/xmlrpc2di/xmlrpc++/src/XmlRpcSocket.h +++ b/apps/xmlrpc2di/xmlrpc++/src/XmlRpcSocket.h @@ -44,7 +44,7 @@ namespace XmlRpc { static bool setReuseAddr(int socket); //! Bind to a specified port - static bool bind(int socket, int port); + static bool bind(int socket, int port, const std::string& bind_ip); //! Set socket in listen mode static bool listen(int socket, int backlog); diff --git a/apps/xmlrpc2di/xmlrpc++/test/HelloServer.cpp b/apps/xmlrpc2di/xmlrpc++/test/HelloServer.cpp index ff81ad8f..b9dfabe5 100644 --- a/apps/xmlrpc2di/xmlrpc++/test/HelloServer.cpp +++ b/apps/xmlrpc2di/xmlrpc++/test/HelloServer.cpp @@ -69,7 +69,7 @@ int main(int argc, char* argv[]) XmlRpc::setVerbosity(5); // Create the server socket on the specified port - s.bindAndListen(port); + s.bindAndListen(port, ""); // Enable introspection s.enableIntrospection(true); diff --git a/apps/xmlrpc2di/xmlrpc++/test/TestBase64Server.cpp b/apps/xmlrpc2di/xmlrpc++/test/TestBase64Server.cpp index c9165929..95baea2c 100644 --- a/apps/xmlrpc2di/xmlrpc++/test/TestBase64Server.cpp +++ b/apps/xmlrpc2di/xmlrpc++/test/TestBase64Server.cpp @@ -58,7 +58,7 @@ int main(int argc, char* argv[]) //XmlRpc::setVerbosity(5); // Create the server socket on the specified port - s.bindAndListen(port); + s.bindAndListen(port, ""); // Wait for requests indefinitely s.work(-1.0); diff --git a/apps/xmlrpc2di/xmlrpc++/test/TestValues.cpp b/apps/xmlrpc2di/xmlrpc++/test/TestValues.cpp index ad726f1c..455f84e9 100644 --- a/apps/xmlrpc2di/xmlrpc++/test/TestValues.cpp +++ b/apps/xmlrpc2di/xmlrpc++/test/TestValues.cpp @@ -1,6 +1,7 @@ // TestValues.cpp : Test XML encoding and decoding of XmlRpcValues. #include +#include #include "XmlRpcValue.h" diff --git a/apps/xmlrpc2di/xmlrpc++/test/Validator.cpp b/apps/xmlrpc2di/xmlrpc++/test/Validator.cpp index 8bbfce53..5ec42d8a 100644 --- a/apps/xmlrpc2di/xmlrpc++/test/Validator.cpp +++ b/apps/xmlrpc2di/xmlrpc++/test/Validator.cpp @@ -197,7 +197,7 @@ int main(int argc, char* argv[]) XmlRpc::setVerbosity(5); // Create the server socket on the specified port - s.bindAndListen(port); + s.bindAndListen(port, ""); // Wait for requests indefinitely s.work(-1.0);