summaryrefslogtreecommitdiff
path: root/cppe/src
diff options
context:
space:
mode:
authorDwayne Boone <dwayne@zeroc.com>2005-10-06 16:18:58 +0000
committerDwayne Boone <dwayne@zeroc.com>2005-10-06 16:18:58 +0000
commita304126403dc5ed49ed1b662d5d51e55d387d645 (patch)
treed0fe36c3c63f3f401769057f9c9f88a9ed829ae2 /cppe/src
parentSupport "-h *" as well (diff)
downloadice-a304126403dc5ed49ed1b662d5d51e55d387d645.tar.bz2
ice-a304126403dc5ed49ed1b662d5d51e55d387d645.tar.xz
ice-a304126403dc5ed49ed1b662d5d51e55d387d645.zip
Bug 395 - support listen on all interfaces
Diffstat (limited to 'cppe/src')
-rw-r--r--cppe/src/IceE/DefaultsAndOverrides.cpp4
-rw-r--r--cppe/src/IceE/Endpoint.h17
-rw-r--r--cppe/src/IceE/EndpointFactory.h2
-rw-r--r--cppe/src/IceE/Network.cpp117
-rw-r--r--cppe/src/IceE/Network.h1
-rw-r--r--cppe/src/IceE/ObjectAdapter.cpp32
-rw-r--r--cppe/src/IceE/ReferenceFactory.cpp2
-rw-r--r--cppe/src/IceE/UnknownEndpoint.cpp13
-rw-r--r--cppe/src/IceE/UnknownEndpoint.h2
-rw-r--r--cppe/src/TcpTransport/EndpointFactory.cpp4
-rw-r--r--cppe/src/TcpTransport/TcpEndpoint.cpp60
-rw-r--r--cppe/src/TcpTransport/TcpEndpoint.h7
12 files changed, 226 insertions, 35 deletions
diff --git a/cppe/src/IceE/DefaultsAndOverrides.cpp b/cppe/src/IceE/DefaultsAndOverrides.cpp
index 9364971bec8..171f07dcff0 100644
--- a/cppe/src/IceE/DefaultsAndOverrides.cpp
+++ b/cppe/src/IceE/DefaultsAndOverrides.cpp
@@ -25,10 +25,6 @@ IceInternal::DefaultsAndOverrides::DefaultsAndOverrides(const PropertiesPtr& pro
overrideConnectTimeoutValue(-1)
{
const_cast<string&>(defaultHost) = properties->getProperty("Ice.Default.Host");
- if(defaultHost.empty())
- {
- const_cast<string&>(defaultHost) = getLocalHost(true);
- }
#ifdef ICEE_HAS_ROUTER
const_cast<string&>(defaultRouter) = properties->getProperty("Ice.Default.Router");
diff --git a/cppe/src/IceE/Endpoint.h b/cppe/src/IceE/Endpoint.h
index 3df8d59b8eb..b7200e67cfb 100644
--- a/cppe/src/IceE/Endpoint.h
+++ b/cppe/src/IceE/Endpoint.h
@@ -82,6 +82,23 @@ public:
#endif
//
+ // Expand endpoint out in to separate endpoints for each local
+ // host if endpoint was configured with no host set. This
+ // only applies for ObjectAdapter endpoints.
+ //
+#ifndef ICEE_PURE_CLIENT
+ virtual std::vector<EndpointPtr> expand() const = 0;
+#endif
+
+ //
+ // Return whether the endpoint should be published in proxies
+ // created by the Object Adapter.
+ //
+#ifndef ICEE_PURE_CLIENT
+ virtual bool publish() const = 0;
+#endif
+
+ //
// Check whether the endpoint is equivalent to a specific
// Transceiver or Acceptor.
//
diff --git a/cppe/src/IceE/EndpointFactory.h b/cppe/src/IceE/EndpointFactory.h
index e816f71ea0f..850b99b815b 100644
--- a/cppe/src/IceE/EndpointFactory.h
+++ b/cppe/src/IceE/EndpointFactory.h
@@ -26,7 +26,7 @@ public:
~EndpointFactory();
- EndpointPtr create(const std::string&) const;
+ EndpointPtr create(const std::string&, bool) const;
EndpointPtr read(BasicStream*) const;
void destroy();
diff --git a/cppe/src/IceE/Network.cpp b/cppe/src/IceE/Network.cpp
index 505468b3168..1c9b430d1cf 100644
--- a/cppe/src/IceE/Network.cpp
+++ b/cppe/src/IceE/Network.cpp
@@ -12,6 +12,18 @@
#include <IceE/LocalException.h>
#include <IceE/SafeStdio.h>
+#if defined(_WIN32)
+# include <winsock2.h>
+#elif defined(__linux) || defined(__APPLE__) || defined(__FreeBSD__)
+# include <ifaddrs.h>
+#else
+# include <sys/ioctl.h>
+# include <net/if.h>
+# ifdef __sun
+# include <sys/sockio.h>
+# endif
+#endif
+
using namespace std;
using namespace Ice;
using namespace IceInternal;
@@ -1002,6 +1014,111 @@ repeatListen:
#endif
+vector<string>
+IceInternal::getLocalHosts()
+{
+ vector<string> result;
+
+#if defined(_WIN32)
+ vector<struct sockaddr_in> addrs = getLocalAddresses();
+ for(unsigned int i = 0; i < addrs.size(); ++i)
+ {
+ result.push_back(inetAddrToString(addrs[i].sin_addr));
+ }
+#elif defined(__linux) || defined(__APPLE__) || defined(__FreeBSD__)
+ struct ifaddrs* ifap;
+ if(::getifaddrs(&ifap) == SOCKET_ERROR)
+ {
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+
+ struct ifaddrs* curr = ifap;
+ while(curr != 0)
+ {
+ if(curr->ifa_addr && curr->ifa_addr->sa_family == AF_INET)
+ {
+ struct sockaddr_in* addr = reinterpret_cast<struct sockaddr_in*>(curr->ifa_addr);
+ if(addr->sin_addr.s_addr != 0)
+ {
+ result.push_back(inetAddrToString((*addr).sin_addr));
+ }
+ }
+
+ curr = curr->ifa_next;
+ }
+
+ ::freeifaddrs(ifap);
+#else
+ SOCKET fd = createSocket(false);
+
+#ifdef _AIX
+ int cmd = CSIOCGIFCONF;
+#else
+ int cmd = SIOCGIFCONF;
+#endif
+ struct ifconf ifc;
+ int numaddrs = 10;
+ int old_ifc_len = 0;
+
+ //
+ // Need to call ioctl multiple times since we do not know up front
+ // how many addresses there will be, and thus how large a buffer we need.
+ // We keep increasing the buffer size until subsequent calls return
+ // the same length, meaning we have all the addresses.
+ //
+ while(true)
+ {
+ int bufsize = numaddrs * sizeof(struct ifreq);
+ ifc.ifc_len = bufsize;
+ ifc.ifc_buf = (char*)malloc(bufsize);
+
+ int rs = ioctl(fd, cmd, &ifc);
+ if(rs == SOCKET_ERROR)
+ {
+ closeSocketNoThrow(fd);
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ else if(ifc.ifc_len == old_ifc_len)
+ {
+ //
+ // Returned same length twice in a row, finished.
+ //
+ break;
+ }
+ else
+ {
+ old_ifc_len = ifc.ifc_len;
+ }
+
+ numaddrs += 10;
+ free(ifc.ifc_buf);
+ }
+
+ numaddrs = ifc.ifc_len / sizeof(struct ifreq);
+ struct ifreq* ifr = ifc.ifc_req;
+ for(int i = 0; i < numaddrs; ++i)
+ {
+ if(ifr[i].ifr_addr.sa_family == AF_INET)
+ {
+ struct sockaddr_in* addr = reinterpret_cast<struct sockaddr_in*>(&ifr[i].ifr_addr);
+ if(addr->sin_addr.s_addr != 0)
+ {
+ result.push_back(inetAddrToString((*addr).sin_addr));
+ }
+ }
+ }
+
+ free(ifc.ifc_buf);
+ closeSocket(fd);
+#endif
+
+ return result;
+}
+
#ifdef _WIN32
vector<struct sockaddr_in>
diff --git a/cppe/src/IceE/Network.h b/cppe/src/IceE/Network.h
index efe8320ac72..cc6ab9fd432 100644
--- a/cppe/src/IceE/Network.h
+++ b/cppe/src/IceE/Network.h
@@ -105,6 +105,7 @@ std::string lastErrorToString();
std::string fdToString(SOCKET);
std::string addrToString(const struct sockaddr_in&);
+std::vector<std::string> getLocalHosts();
#ifdef _WIN32
std::vector<struct sockaddr_in> getLocalAddresses();
bool isLocalAddress(const struct sockaddr_in&);
diff --git a/cppe/src/IceE/ObjectAdapter.cpp b/cppe/src/IceE/ObjectAdapter.cpp
index 878e9934f09..613d639e1bb 100644
--- a/cppe/src/IceE/ObjectAdapter.cpp
+++ b/cppe/src/IceE/ObjectAdapter.cpp
@@ -682,6 +682,17 @@ Ice::ObjectAdapter::ObjectAdapter(const InstancePtr& instance, const Communicato
//
string endpts = _instance->properties()->getProperty(name + ".PublishedEndpoints");
_publishedEndpoints = parseEndpoints(endpts);
+ if(_publishedEndpoints.empty())
+ {
+ transform(_incomingConnectionFactories.begin(), _incomingConnectionFactories.end(),
+ back_inserter(_publishedEndpoints), Ice::constMemFun(&IncomingConnectionFactory::endpoint));
+ }
+
+ //
+ // Filter out any endpoints that are not meant to be published.
+ //
+ _publishedEndpoints.erase(remove_if(_publishedEndpoints.begin(), _publishedEndpoints.end(),
+ not1(Ice::constMemFun(&Endpoint::publish))), _publishedEndpoints.end());
#ifdef ICEE_HAS_ROUTER
string router = _instance->properties()->getProperty(_name + ".Router");
@@ -770,21 +781,7 @@ Ice::ObjectAdapter::newProxy(const Identity& ident, const string& facet) const
ObjectPrx
Ice::ObjectAdapter::newDirectProxy(const Identity& ident, const string& facet) const
{
- vector<EndpointPtr> endpoints;
-
- //
- // Use the published endpoints, otherwise use the endpoints from all
- // incoming connection factories.
- //
- if(!_publishedEndpoints.empty())
- {
- endpoints = _publishedEndpoints;
- }
- else
- {
- transform(_incomingConnectionFactories.begin(), _incomingConnectionFactories.end(), back_inserter(endpoints),
- Ice::constMemFun(&IncomingConnectionFactory::endpoint));
- }
+ vector<EndpointPtr> endpoints = _publishedEndpoints;
//
// Now we also add the endpoints of the router's server proxy, if
@@ -864,14 +861,15 @@ Ice::ObjectAdapter::parseEndpoints(const string& str) const
}
string s = endpts.substr(beg, end - beg);
- EndpointPtr endp = _instance->endpointFactory()->create(s);
+ EndpointPtr endp = _instance->endpointFactory()->create(s, true);
if(endp == 0)
{
EndpointParseException ex(__FILE__, __LINE__);
ex.str = s;
throw ex;
}
- endpoints.push_back(endp);
+ vector<EndpointPtr> endps = endp->expand();
+ endpoints.insert(endpoints.end(), endps.begin(), endps.end());
++end;
}
diff --git a/cppe/src/IceE/ReferenceFactory.cpp b/cppe/src/IceE/ReferenceFactory.cpp
index 36282a05c26..59cad2db6aa 100644
--- a/cppe/src/IceE/ReferenceFactory.cpp
+++ b/cppe/src/IceE/ReferenceFactory.cpp
@@ -461,7 +461,7 @@ IceInternal::ReferenceFactory::create(const string& str)
}
string es = s.substr(beg, end - beg);
- EndpointPtr endp = _instance->endpointFactory()->create(es);
+ EndpointPtr endp = _instance->endpointFactory()->create(es, false);
if(endp != 0)
{
endpoints.push_back(endp);
diff --git a/cppe/src/IceE/UnknownEndpoint.cpp b/cppe/src/IceE/UnknownEndpoint.cpp
index 3c259628faa..9384093b257 100644
--- a/cppe/src/IceE/UnknownEndpoint.cpp
+++ b/cppe/src/IceE/UnknownEndpoint.cpp
@@ -78,6 +78,19 @@ IceInternal::UnknownEndpoint::acceptor(EndpointPtr& endp) const
endp = const_cast<UnknownEndpoint*>(this);
return 0;
}
+
+std::vector<EndpointPtr>
+IceInternal::UnknownEndpoint::expand() const
+{
+ assert(false);
+}
+
+bool
+IceInternal::UnknownEndpoint::publish() const
+{
+ return false;
+}
+
#endif
bool
diff --git a/cppe/src/IceE/UnknownEndpoint.h b/cppe/src/IceE/UnknownEndpoint.h
index 16e5fbf33c6..bf1c5e93eb2 100644
--- a/cppe/src/IceE/UnknownEndpoint.h
+++ b/cppe/src/IceE/UnknownEndpoint.h
@@ -30,6 +30,8 @@ public:
virtual ConnectorPtr connector() const;
#ifndef ICEE_PURE_CLIENT
virtual AcceptorPtr acceptor(EndpointPtr&) const;
+ virtual std::vector<EndpointPtr> expand() const;
+ virtual bool publish() const;
#endif
virtual bool equivalent(const TransceiverPtr&) const;
#ifndef ICEE_PURE_CLIENT
diff --git a/cppe/src/TcpTransport/EndpointFactory.cpp b/cppe/src/TcpTransport/EndpointFactory.cpp
index 11b09c7227e..9e44b23af9f 100644
--- a/cppe/src/TcpTransport/EndpointFactory.cpp
+++ b/cppe/src/TcpTransport/EndpointFactory.cpp
@@ -30,7 +30,7 @@ IceInternal::EndpointFactory::~EndpointFactory()
}
EndpointPtr
-IceInternal::EndpointFactory::create(const std::string& str) const
+IceInternal::EndpointFactory::create(const std::string& str, bool adapterEndp) const
{
const string delim = " \t\n\r";
@@ -52,7 +52,7 @@ IceInternal::EndpointFactory::create(const std::string& str) const
if(protocol == "default" || protocol == "tcp")
{
- return new TcpEndpoint(_instance, str.substr(end));
+ return new TcpEndpoint(_instance, str.substr(end), adapterEndp);
}
return 0;
diff --git a/cppe/src/TcpTransport/TcpEndpoint.cpp b/cppe/src/TcpTransport/TcpEndpoint.cpp
index 22461413606..79c9ab0c76b 100644
--- a/cppe/src/TcpTransport/TcpEndpoint.cpp
+++ b/cppe/src/TcpTransport/TcpEndpoint.cpp
@@ -24,18 +24,20 @@ using namespace std;
using namespace Ice;
using namespace IceInternal;
-IceInternal::TcpEndpoint::TcpEndpoint(const InstancePtr& instance, const string& ho, Int po, Int ti) :
+IceInternal::TcpEndpoint::TcpEndpoint(const InstancePtr& instance, const string& ho, Int po, Int ti, bool pub) :
_instance(instance),
_host(ho),
_port(po),
- _timeout(ti)
+ _timeout(ti),
+ _publish(pub)
{
}
-IceInternal::TcpEndpoint::TcpEndpoint(const InstancePtr& instance, const string& str) :
+IceInternal::TcpEndpoint::TcpEndpoint(const InstancePtr& instance, const string& str, bool adapterEndp) :
_instance(instance),
_port(0),
- _timeout(-1)
+ _timeout(-1),
+ _publish(true)
{
const string delim = " \t\n\r";
@@ -132,14 +134,30 @@ IceInternal::TcpEndpoint::TcpEndpoint(const InstancePtr& instance, const string&
if(_host.empty())
{
- const_cast<string&>(_host) = _instance->defaultsAndOverrides()->defaultHost;
+ const_cast<string&>(_host) = _instance->defaultsAndOverrides()->defaultHost;
+ if(_host.empty())
+ {
+ if(adapterEndp)
+ {
+ const_cast<string&>(_host) = "0.0.0.0";
+ }
+ else
+ {
+ const_cast<string&>(_host) = getLocalHost(true);
+ }
+ }
+ }
+ else if(_host == "*" && adapterEndp)
+ {
+ const_cast<string&>(_host) = "0.0.0.0";
}
}
IceInternal::TcpEndpoint::TcpEndpoint(BasicStream* s) :
_instance(s->instance()),
_port(0),
- _timeout(-1)
+ _timeout(-1),
+ _publish(true)
{
bool dummy;
@@ -200,7 +218,7 @@ IceInternal::TcpEndpoint::timeout(Int timeout) const
}
else
{
- return new TcpEndpoint(_instance, _host, _port, timeout);
+ return new TcpEndpoint(_instance, _host, _port, timeout, _publish);
}
}
@@ -343,10 +361,36 @@ AcceptorPtr
IceInternal::TcpEndpoint::acceptor(EndpointPtr& endp) const
{
Acceptor* p = new Acceptor(_instance, _host, _port);
- endp = new TcpEndpoint(_instance, _host, p->effectivePort(), _timeout);
+ endp = new TcpEndpoint(_instance, _host, p->effectivePort(), _timeout, _publish);
return p;
}
+vector<EndpointPtr>
+IceInternal::TcpEndpoint::expand() const
+{
+ vector<EndpointPtr> endps;
+ if(_host == "0.0.0.0")
+ {
+ vector<string> hosts = getLocalHosts();
+ for(unsigned int i = 0; i < hosts.size(); ++i)
+ {
+ endps.push_back(new TcpEndpoint(_instance, hosts[i], _port, _timeout,
+ hosts.size() == 1 || hosts[i] != "127.0.0.1"));
+ }
+ }
+ else
+ {
+ endps.push_back(const_cast<TcpEndpoint*>(this));
+ }
+ return endps;
+}
+
+bool
+IceInternal::TcpEndpoint::publish() const
+{
+ return _publish;
+}
+
bool
IceInternal::TcpEndpoint::equivalent(const AcceptorPtr& acceptor) const
{
diff --git a/cppe/src/TcpTransport/TcpEndpoint.h b/cppe/src/TcpTransport/TcpEndpoint.h
index 0880ca794a0..dd2760e62e4 100644
--- a/cppe/src/TcpTransport/TcpEndpoint.h
+++ b/cppe/src/TcpTransport/TcpEndpoint.h
@@ -21,8 +21,8 @@ class TcpEndpoint : public IceInternal::Endpoint
{
public:
- TcpEndpoint(const InstancePtr&, const std::string&, Ice::Int, Ice::Int);
- TcpEndpoint(const InstancePtr&, const std::string&);
+ TcpEndpoint(const InstancePtr&, const std::string&, Ice::Int, Ice::Int, bool);
+ TcpEndpoint(const InstancePtr&, const std::string&, bool);
TcpEndpoint(BasicStream*);
virtual void streamWrite(BasicStream*) const;
@@ -34,6 +34,8 @@ public:
virtual ConnectorPtr connector() const;
#ifndef ICEE_PURE_CLIENT
virtual AcceptorPtr acceptor(EndpointPtr&) const;
+ virtual std::vector<EndpointPtr> expand() const;
+ virtual bool publish() const;
#endif
virtual bool equivalent(const TransceiverPtr&) const;
#ifndef ICEE_PURE_CLIENT
@@ -53,6 +55,7 @@ private:
const std::string _host;
const Ice::Int _port;
const Ice::Int _timeout;
+ const bool _publish;
};
}