diff options
46 files changed, 799 insertions, 105 deletions
diff --git a/CHANGELOG-3.7.md b/CHANGELOG-3.7.md index 42b58b79757..0f3466dd020 100644 --- a/CHANGELOG-3.7.md +++ b/CHANGELOG-3.7.md @@ -25,6 +25,16 @@ These are the changes since the Ice 3.6 release or snapshot described in ## General Changes +- The server runtime will now bind to all the addresses associated with a DNS + name specified in an endpoint of the object adapter (with the endpoint -h + option). You must make sure the DNS name resolves to local addresses only. + + If no PublishedEndpoints property is specified for the object adapter, the + published endpoints for an endpoint with a DNS name will either be, if the + endpoint doesn't specifies a fixed port, a list of endpoints with each of + the addresses associated with the DNS name or, if it specifies a fixed port, + the endpoint with the DNS name. + - Added the IceBridge service, which acts as a bridge between a client and server to relay requests and replies in both directions. diff --git a/cpp/src/Ice/ConnectionFactory.cpp b/cpp/src/Ice/ConnectionFactory.cpp index 51f2c58cfb7..0858c97a556 100644 --- a/cpp/src/Ice/ConnectionFactory.cpp +++ b/cpp/src/Ice/ConnectionFactory.cpp @@ -1255,10 +1255,25 @@ IceInternal::IncomingConnectionFactory::waitUntilFinished() } } +bool +IceInternal::IncomingConnectionFactory::isLocal(const EndpointIPtr& endpoint) const +{ + if(_publishedEndpoint && endpoint->equivalent(_publishedEndpoint)) + { + return true; + } + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + return endpoint->equivalent(_endpoint); +} + EndpointIPtr IceInternal::IncomingConnectionFactory::endpoint() const { - // No mutex protection necessary, _endpoint is immutable. + if(_publishedEndpoint) + { + return _publishedEndpoint; + } + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); return _endpoint; } @@ -1561,10 +1576,12 @@ IceInternal::IncomingConnectionFactory::connectionStartFailed(const Ice::Connect // IceInternal::IncomingConnectionFactory::IncomingConnectionFactory(const InstancePtr& instance, const EndpointIPtr& endpoint, + const EndpointIPtr& publishedEndpoint, const ObjectAdapterIPtr& adapter) : _instance(instance), _monitor(new FactoryACMMonitor(instance, dynamic_cast<ObjectAdapterI*>(adapter.get())->getACM())), _endpoint(endpoint), + _publishedEndpoint(publishedEndpoint), _acceptorStarted(false), _acceptorStopped(false), _adapter(adapter), diff --git a/cpp/src/Ice/ConnectionFactory.h b/cpp/src/Ice/ConnectionFactory.h index 2bc809c1fca..13b41cabd17 100644 --- a/cpp/src/Ice/ConnectionFactory.h +++ b/cpp/src/Ice/ConnectionFactory.h @@ -189,6 +189,7 @@ public: void waitUntilHolding() const; void waitUntilFinished(); + bool isLocal(const EndpointIPtr&) const; EndpointIPtr endpoint() const; std::list<Ice::ConnectionIPtr> connections() const; void flushAsyncBatchRequests(const CommunicatorFlushBatchAsyncPtr&, Ice::CompressBatch); @@ -210,7 +211,8 @@ public: virtual void connectionStartCompleted(const Ice::ConnectionIPtr&); virtual void connectionStartFailed(const Ice::ConnectionIPtr&, const Ice::LocalException&); - IncomingConnectionFactory(const InstancePtr&, const EndpointIPtr&, const Ice::ObjectAdapterIPtr&); + IncomingConnectionFactory(const InstancePtr&, const EndpointIPtr&, const EndpointIPtr&, + const Ice::ObjectAdapterIPtr&); void initialize(); virtual ~IncomingConnectionFactory(); @@ -244,6 +246,7 @@ private: AcceptorPtr _acceptor; const TransceiverPtr _transceiver; EndpointIPtr _endpoint; + EndpointIPtr _publishedEndpoint; bool _acceptorStarted; bool _acceptorStopped; diff --git a/cpp/src/Ice/EndpointI.h b/cpp/src/Ice/EndpointI.h index 5cb10fc1040..8ff79a80b3a 100644 --- a/cpp/src/Ice/EndpointI.h +++ b/cpp/src/Ice/EndpointI.h @@ -128,10 +128,21 @@ public: virtual AcceptorPtr acceptor(const std::string&) const = 0; // - // Expand endpoint out in to separate endpoints for each local + // Expand endpoint out into separate endpoints for each local // host if listening on INADDR_ANY on server side. // - virtual std::vector<EndpointIPtr> expand() const = 0; + virtual std::vector<EndpointIPtr> expandIfWildcard() const = 0; + + // + // Expand endpoint out into separate endpoints for each IP + // address returned by the DNS resolver. Also returns the + // endpoint which can be used to connect to the returned + // endpoints or null if no specific endpoint can be used to + // connect to these endpoints (e.g.: with the IP endpoint, + // it returns this endpoint if it uses a fixed port, null + // otherwise). + // + virtual std::vector<EndpointIPtr> expandHost(IceInternal::EndpointIPtr&) const = 0; // // Check whether the endpoint is equivalent to another one. diff --git a/cpp/src/Ice/IPEndpointI.cpp b/cpp/src/Ice/IPEndpointI.cpp index 86ffd787ec2..476fc3b809c 100644 --- a/cpp/src/Ice/IPEndpointI.cpp +++ b/cpp/src/Ice/IPEndpointI.cpp @@ -138,7 +138,7 @@ IceInternal::IPEndpointI::connectors_async(Ice::EndpointSelectionType selType, c } vector<EndpointIPtr> -IceInternal::IPEndpointI::expand() const +IceInternal::IPEndpointI::expandIfWildcard() const { vector<EndpointIPtr> endps; vector<string> hosts = getHostsForEndpointExpand(_host, _instance->protocolSupport(), false); @@ -156,6 +156,55 @@ IceInternal::IPEndpointI::expand() const return endps; } +vector<EndpointIPtr> +IceInternal::IPEndpointI::expandHost(EndpointIPtr& publish) const +{ + // + // If this endpoint has an empty host (wildcard address), don't expand, just return + // this endpoint. + // + if(_host.empty()) + { + vector<EndpointIPtr> endpoints; + endpoints.push_back(ICE_SHARED_FROM_CONST_THIS(IPEndpointI)); + return endpoints; + } + + // + // If using a fixed port, this endpoint can be used as the published endpoint to + // access the returned endpoints. Otherwise, we'll publish each individual expanded + // endpoint. + // + if(_port > 0) + { + publish = ICE_SHARED_FROM_CONST_THIS(IPEndpointI); + } + + vector<Address> addrs = getAddresses(_host, + _port, + _instance->protocolSupport(), + Ice::ICE_ENUM(EndpointSelectionType, Ordered), + _instance->preferIPv6(), + true); + + vector<EndpointIPtr> endpoints; + if(addrs.size() == 1) + { + endpoints.push_back(ICE_SHARED_FROM_CONST_THIS(IPEndpointI)); + } + else + { + for(vector<Address>::const_iterator p = addrs.begin(); p != addrs.end(); ++p) + { + string host; + int port; + addrToAddressAndPort(*p, host, port); + endpoints.push_back(createEndpoint(host, port, _connectionId)); + } + } + return endpoints; +} + bool IceInternal::IPEndpointI::equivalent(const EndpointIPtr& endpoint) const { @@ -634,7 +683,8 @@ IceInternal::EndpointHostResolver::run() if(threadObserver) { - threadObserver->stateChanged(ICE_ENUM(ThreadState, ThreadStateInUseForOther), ICE_ENUM(ThreadState, ThreadStateIdle)); + threadObserver->stateChanged(ICE_ENUM(ThreadState, ThreadStateInUseForOther), + ICE_ENUM(ThreadState, ThreadStateIdle)); } } @@ -642,7 +692,8 @@ IceInternal::EndpointHostResolver::run() { if(threadObserver) { - threadObserver->stateChanged(ICE_ENUM(ThreadState, ThreadStateInUseForOther), ICE_ENUM(ThreadState, ThreadStateIdle)); + threadObserver->stateChanged(ICE_ENUM(ThreadState, ThreadStateInUseForOther), + ICE_ENUM(ThreadState, ThreadStateIdle)); } if(r.observer) { @@ -678,7 +729,10 @@ IceInternal::EndpointHostResolver::updateObserver() const CommunicatorObserverPtr& obsv = _instance->initializationData().observer; if(obsv) { - _observer.attach(obsv->getThreadObserver("Communicator", name(), ICE_ENUM(ThreadState, ThreadStateIdle), _observer.get())); + _observer.attach(obsv->getThreadObserver("Communicator", + name(), + ICE_ENUM(ThreadState, ThreadStateIdle), + _observer.get())); } } diff --git a/cpp/src/Ice/IPEndpointI.h b/cpp/src/Ice/IPEndpointI.h index 4f51e5a9ff7..bfe1c6f97ec 100644 --- a/cpp/src/Ice/IPEndpointI.h +++ b/cpp/src/Ice/IPEndpointI.h @@ -61,7 +61,8 @@ public: virtual EndpointIPtr connectionId(const ::std::string&) const; virtual void connectors_async(Ice::EndpointSelectionType, const EndpointI_connectorsPtr&) const; - virtual std::vector<EndpointIPtr> expand() const; + virtual std::vector<EndpointIPtr> expandIfWildcard() const; + virtual std::vector<EndpointIPtr> expandHost(EndpointIPtr&) const; virtual bool equivalent(const EndpointIPtr&) const; virtual ::Ice::Int hash() const; virtual std::string options() const; diff --git a/cpp/src/Ice/Network.cpp b/cpp/src/Ice/Network.cpp index 599f6537896..b1c48af121b 100755 --- a/cpp/src/Ice/Network.cpp +++ b/cpp/src/Ice/Network.cpp @@ -2364,7 +2364,8 @@ IceInternal::doBind(SOCKET fd, const Address& addr, const string&) Address IceInternal::getNumericAddress(const std::string& address) { - vector<Address> addrs = getAddresses(address, 0, EnableBoth, Ice::ICE_ENUM(EndpointSelectionType, Ordered), false, false); + vector<Address> addrs = getAddresses(address, 0, EnableBoth, Ice::ICE_ENUM(EndpointSelectionType, Ordered), false, + false); if(addrs.empty()) { return Address(); diff --git a/cpp/src/Ice/ObjectAdapterI.cpp b/cpp/src/Ice/ObjectAdapterI.cpp index 5de6bf0acaa..bc22131f8cf 100644 --- a/cpp/src/Ice/ObjectAdapterI.cpp +++ b/cpp/src/Ice/ObjectAdapterI.cpp @@ -787,7 +787,7 @@ Ice::ObjectAdapterI::isLocal(const ObjectPrxPtr& proxy) const for(vector<IncomingConnectionFactoryPtr>::const_iterator q = _incomingConnectionFactories.begin(); q != _incomingConnectionFactories.end(); ++q) { - if((*p)->equivalent((*q)->endpoint())) + if((*q)->isLocal(*p)) { return true; } @@ -1102,11 +1102,19 @@ Ice::ObjectAdapterI::initialize(const RouterPrxPtr& router) vector<EndpointIPtr> endpoints = parseEndpoints(properties->getProperty(_name + ".Endpoints"), true); for(vector<EndpointIPtr>::iterator p = endpoints.begin(); p != endpoints.end(); ++p) { - IncomingConnectionFactoryPtr factory = ICE_MAKE_SHARED(IncomingConnectionFactory, _instance, *p, ICE_SHARED_FROM_THIS); - factory->initialize(); - _incomingConnectionFactories.push_back(factory); + EndpointIPtr publishedEndpoint; + vector<EndpointIPtr> expanded = (*p)->expandHost(publishedEndpoint); + for(vector<EndpointIPtr>::iterator q = expanded.begin(); q != expanded.end(); ++q) + { + IncomingConnectionFactoryPtr factory = ICE_MAKE_SHARED(IncomingConnectionFactory, + _instance, + *q, + publishedEndpoint, + ICE_SHARED_FROM_THIS); + factory->initialize(); + _incomingConnectionFactories.push_back(factory); + } } - if(endpoints.empty()) { TraceLevelsPtr tl = _instance->traceLevels(); @@ -1322,8 +1330,19 @@ ObjectAdapterI::parsePublishedEndpoints() // for(unsigned int i = 0; i < _incomingConnectionFactories.size(); ++i) { - vector<EndpointIPtr> endps = _incomingConnectionFactories[i]->endpoint()->expand(); - endpoints.insert(endpoints.end(), endps.begin(), endps.end()); + vector<EndpointIPtr> endps = _incomingConnectionFactories[i]->endpoint()->expandIfWildcard(); + for(vector<EndpointIPtr>::const_iterator p = endps.begin(); p != endps.end(); ++p) + { + // + // Check for duplicate endpoints, this might occur if an endpoint with a DNS name + // expands to multiple addresses. In this case, multiple incoming connection + // factories can point to the same published endpoint. + // + if(::find(endpoints.begin(), endpoints.end(), *p) == endpoints.end()) + { + endpoints.push_back(*p); + } + } } } diff --git a/cpp/src/Ice/OpaqueEndpointI.cpp b/cpp/src/Ice/OpaqueEndpointI.cpp index 77da8121e7f..065af32eae9 100644 --- a/cpp/src/Ice/OpaqueEndpointI.cpp +++ b/cpp/src/Ice/OpaqueEndpointI.cpp @@ -190,7 +190,15 @@ IceInternal::OpaqueEndpointI::acceptor(const string&) const } vector<EndpointIPtr> -IceInternal::OpaqueEndpointI::expand() const +IceInternal::OpaqueEndpointI::expandIfWildcard() const +{ + vector<EndpointIPtr> endps; + endps.push_back(ICE_SHARED_FROM_CONST_THIS(OpaqueEndpointI)); + return endps; +} + +vector<EndpointIPtr> +IceInternal::OpaqueEndpointI::expandHost(EndpointIPtr&) const { vector<EndpointIPtr> endps; endps.push_back(ICE_SHARED_FROM_CONST_THIS(OpaqueEndpointI)); diff --git a/cpp/src/Ice/OpaqueEndpointI.h b/cpp/src/Ice/OpaqueEndpointI.h index 582764bfd30..873706abd53 100644 --- a/cpp/src/Ice/OpaqueEndpointI.h +++ b/cpp/src/Ice/OpaqueEndpointI.h @@ -43,7 +43,8 @@ public: virtual TransceiverPtr transceiver() const; virtual void connectors_async(Ice::EndpointSelectionType, const EndpointI_connectorsPtr&) const; virtual AcceptorPtr acceptor(const std::string&) const; - virtual std::vector<EndpointIPtr> expand() const; + virtual std::vector<EndpointIPtr> expandIfWildcard() const; + virtual std::vector<EndpointIPtr> expandHost(EndpointIPtr&) const; virtual bool equivalent(const EndpointIPtr&) const; virtual Ice::Int hash() const; virtual std::string options() const; diff --git a/cpp/src/Ice/WSEndpoint.cpp b/cpp/src/Ice/WSEndpoint.cpp index 974f998412a..c19842d652f 100644 --- a/cpp/src/Ice/WSEndpoint.cpp +++ b/cpp/src/Ice/WSEndpoint.cpp @@ -232,12 +232,45 @@ IceInternal::WSEndpoint::endpoint(const EndpointIPtr& delEndp) const } vector<EndpointIPtr> -IceInternal::WSEndpoint::expand() const +IceInternal::WSEndpoint::expandIfWildcard() const { - vector<EndpointIPtr> endps = _delegate->expand(); + vector<EndpointIPtr> endps = _delegate->expandIfWildcard(); for(vector<EndpointIPtr>::iterator p = endps.begin(); p != endps.end(); ++p) { - *p = p->get() == _delegate.get() ? ICE_SHARED_FROM_CONST_THIS(WSEndpoint) : ICE_MAKE_SHARED(WSEndpoint, _instance, *p, _resource); + if(p->get() == _delegate.get()) + { + *p = ICE_SHARED_FROM_CONST_THIS(WSEndpoint); + } + else + { + *p = ICE_MAKE_SHARED(WSEndpoint, _instance, *p, _resource); + } + } + return endps; +} + +vector<EndpointIPtr> +IceInternal::WSEndpoint::expandHost(EndpointIPtr& publish) const +{ + vector<EndpointIPtr> endps = _delegate->expandHost(publish); + if(publish.get() == _delegate.get()) + { + publish = ICE_SHARED_FROM_CONST_THIS(WSEndpoint); + } + else if(publish.get()) + { + publish = ICE_MAKE_SHARED(WSEndpoint, _instance, publish, _resource); + } + for(vector<EndpointIPtr>::iterator p = endps.begin(); p != endps.end(); ++p) + { + if(p->get() == _delegate.get()) + { + *p = ICE_SHARED_FROM_CONST_THIS(WSEndpoint); + } + else + { + *p = ICE_MAKE_SHARED(WSEndpoint, _instance, *p, _resource); + } } return endps; } diff --git a/cpp/src/Ice/WSEndpoint.h b/cpp/src/Ice/WSEndpoint.h index 23ffe0ddb1e..fe38fe331cf 100644 --- a/cpp/src/Ice/WSEndpoint.h +++ b/cpp/src/Ice/WSEndpoint.h @@ -49,8 +49,8 @@ public: virtual TransceiverPtr transceiver() const; virtual void connectors_async(Ice::EndpointSelectionType, const EndpointI_connectorsPtr&) const; virtual AcceptorPtr acceptor(const std::string&) const; - - virtual std::vector<EndpointIPtr> expand() const; + virtual std::vector<EndpointIPtr> expandIfWildcard() const; + virtual std::vector<EndpointIPtr> expandHost(EndpointIPtr&) const; virtual bool equivalent(const EndpointIPtr&) const; virtual ::Ice::Int hash() const; virtual std::string options() const; diff --git a/cpp/src/IceBT/EndpointI.cpp b/cpp/src/IceBT/EndpointI.cpp index 1209dc8f121..a081b36747f 100644 --- a/cpp/src/IceBT/EndpointI.cpp +++ b/cpp/src/IceBT/EndpointI.cpp @@ -185,7 +185,18 @@ IceBT::EndpointI::acceptor(const string& adapterName) const } vector<IceInternal::EndpointIPtr> -IceBT::EndpointI::expand() const +IceBT::EndpointI::expandIfWildcard() const +{ + // + // Nothing to do here. + // + vector<IceInternal::EndpointIPtr> endps; + endps.push_back(ICE_SHARED_FROM_CONST_THIS(EndpointI)); + return endps; +} + +vector<IceInternal::EndpointIPtr> +IceBT::EndpointI::expandHost(IceInternal::EndpointIPtr&) const { // // Nothing to do here. diff --git a/cpp/src/IceBT/EndpointI.h b/cpp/src/IceBT/EndpointI.h index bc935428965..8e322574a1f 100644 --- a/cpp/src/IceBT/EndpointI.h +++ b/cpp/src/IceBT/EndpointI.h @@ -47,7 +47,8 @@ public: virtual IceInternal::TransceiverPtr transceiver() const; virtual void connectors_async(Ice::EndpointSelectionType, const IceInternal::EndpointI_connectorsPtr&) const; virtual IceInternal::AcceptorPtr acceptor(const std::string&) const; - virtual std::vector<IceInternal::EndpointIPtr> expand() const; + virtual std::vector<IceInternal::EndpointIPtr> expandIfWildcard() const; + virtual std::vector<IceInternal::EndpointIPtr> expandHost(IceInternal::EndpointIPtr&) const; virtual bool equivalent(const IceInternal::EndpointIPtr&) const; #ifdef ICE_CPP11_MAPPING diff --git a/cpp/src/IceIAP/EndpointI.h b/cpp/src/IceIAP/EndpointI.h index 1194a6450da..8e71869eb70 100644 --- a/cpp/src/IceIAP/EndpointI.h +++ b/cpp/src/IceIAP/EndpointI.h @@ -54,8 +54,8 @@ public: virtual IceInternal::TransceiverPtr transceiver() const; virtual void connectors_async(Ice::EndpointSelectionType, const IceInternal::EndpointI_connectorsPtr&) const; virtual IceInternal::AcceptorPtr acceptor(const std::string&) const; - - virtual std::vector<IceInternal::EndpointIPtr> expand() const; + virtual std::vector<IceInternal::EndpointIPtr> expandIfWildcard() const; + virtual std::vector<IceInternal::EndpointIPtr> expandHost(IceInternal::EndpointIPtr&) const; virtual bool equivalent(const IceInternal::EndpointIPtr&) const; #ifdef ICE_CPP11_MAPPING diff --git a/cpp/src/IceIAP/EndpointI.mm b/cpp/src/IceIAP/EndpointI.mm index 87c071cbb69..1914e3e79ba 100644 --- a/cpp/src/IceIAP/EndpointI.mm +++ b/cpp/src/IceIAP/EndpointI.mm @@ -300,7 +300,15 @@ IceObjC::iAPEndpointI::acceptor(const string&) const } vector<EndpointIPtr> -IceObjC::iAPEndpointI::expand() const +IceObjC::iAPEndpointI::expandIfWildcard() const +{ + vector<EndpointIPtr> endps; + endps.push_back(ICE_SHARED_FROM_CONST_THIS(iAPEndpointI)); + return endps; +} + +vector<EndpointIPtr> +IceObjC::iAPEndpointI::expandHost(EndpointIPtr&) const { vector<EndpointIPtr> endps; endps.push_back(ICE_SHARED_FROM_CONST_THIS(iAPEndpointI)); diff --git a/cpp/src/IceSSL/EndpointI.cpp b/cpp/src/IceSSL/EndpointI.cpp index 972c220b7dd..2300bffa4cb 100644 --- a/cpp/src/IceSSL/EndpointI.cpp +++ b/cpp/src/IceSSL/EndpointI.cpp @@ -207,12 +207,45 @@ IceSSL::EndpointI::endpoint(const IceInternal::EndpointIPtr& delEndp) const } vector<IceInternal::EndpointIPtr> -IceSSL::EndpointI::expand() const +IceSSL::EndpointI::expandIfWildcard() const { - vector<IceInternal::EndpointIPtr> endps = _delegate->expand(); + vector<IceInternal::EndpointIPtr> endps = _delegate->expandIfWildcard(); for(vector<IceInternal::EndpointIPtr>::iterator p = endps.begin(); p != endps.end(); ++p) { - *p = p->get() == _delegate.get() ? ICE_SHARED_FROM_CONST_THIS(EndpointI) : ICE_MAKE_SHARED(EndpointI, _instance, *p); + if(p->get() == _delegate.get()) + { + *p = ICE_SHARED_FROM_CONST_THIS(EndpointI); + } + else + { + *p = ICE_MAKE_SHARED(EndpointI, _instance, *p); + } + } + return endps; +} + +vector<IceInternal::EndpointIPtr> +IceSSL::EndpointI::expandHost(IceInternal::EndpointIPtr& publish) const +{ + vector<IceInternal::EndpointIPtr> endps = _delegate->expandHost(publish); + if(publish.get() == _delegate.get()) + { + publish = ICE_SHARED_FROM_CONST_THIS(EndpointI); + } + else if(publish.get()) + { + publish = ICE_MAKE_SHARED(EndpointI, _instance, publish); + } + for(vector<IceInternal::EndpointIPtr>::iterator p = endps.begin(); p != endps.end(); ++p) + { + if(p->get() == _delegate.get()) + { + *p = ICE_SHARED_FROM_CONST_THIS(EndpointI); + } + else + { + *p = ICE_MAKE_SHARED(EndpointI, _instance, *p); + } } return endps; } diff --git a/cpp/src/IceSSL/EndpointI.h b/cpp/src/IceSSL/EndpointI.h index 413aa99a6dd..d27a7182a4a 100644 --- a/cpp/src/IceSSL/EndpointI.h +++ b/cpp/src/IceSSL/EndpointI.h @@ -47,8 +47,8 @@ public: virtual IceInternal::TransceiverPtr transceiver() const; virtual void connectors_async(Ice::EndpointSelectionType, const IceInternal::EndpointI_connectorsPtr&) const; virtual IceInternal::AcceptorPtr acceptor(const std::string&) const; - - virtual std::vector<IceInternal::EndpointIPtr> expand() const; + virtual std::vector<IceInternal::EndpointIPtr> expandIfWildcard() const; + virtual std::vector<IceInternal::EndpointIPtr> expandHost(IceInternal::EndpointIPtr&) const; virtual bool equivalent(const IceInternal::EndpointIPtr&) const; virtual ::Ice::Int hash() const; virtual std::string options() const; diff --git a/cpp/test/Ice/background/EndpointI.cpp b/cpp/test/Ice/background/EndpointI.cpp index dd0ae6dcd2a..965d64fafea 100644 --- a/cpp/test/Ice/background/EndpointI.cpp +++ b/cpp/test/Ice/background/EndpointI.cpp @@ -212,9 +212,24 @@ EndpointI::endpoint(const IceInternal::EndpointIPtr& delEndp) const } vector<IceInternal::EndpointIPtr> -EndpointI::expand() const +EndpointI::expandIfWildcard() const { - vector<IceInternal::EndpointIPtr> e = _endpoint->expand(); + vector<IceInternal::EndpointIPtr> e = _endpoint->expandIfWildcard(); + for(vector<IceInternal::EndpointIPtr>::iterator p = e.begin(); p != e.end(); ++p) + { + *p = (*p == _endpoint) ? ICE_SHARED_FROM_CONST_THIS(EndpointI) : ICE_MAKE_SHARED(EndpointI, *p); + } + return e; +} + +vector<IceInternal::EndpointIPtr> +EndpointI::expandHost(IceInternal::EndpointIPtr& publish) const +{ + vector<IceInternal::EndpointIPtr> e = _endpoint->expandHost(publish); + if(publish) + { + publish = publish == _endpoint ? ICE_SHARED_FROM_CONST_THIS(EndpointI) : ICE_MAKE_SHARED(EndpointI, publish); + } for(vector<IceInternal::EndpointIPtr>::iterator p = e.begin(); p != e.end(); ++p) { *p = (*p == _endpoint) ? ICE_SHARED_FROM_CONST_THIS(EndpointI) : ICE_MAKE_SHARED(EndpointI, *p); diff --git a/cpp/test/Ice/background/EndpointI.h b/cpp/test/Ice/background/EndpointI.h index 2c70a1dfb4e..46231d7d602 100644 --- a/cpp/test/Ice/background/EndpointI.h +++ b/cpp/test/Ice/background/EndpointI.h @@ -39,8 +39,8 @@ public: virtual IceInternal::TransceiverPtr transceiver() const; virtual void connectors_async(Ice::EndpointSelectionType, const IceInternal::EndpointI_connectorsPtr&) const; virtual IceInternal::AcceptorPtr acceptor(const std::string&) const; - - virtual std::vector<IceInternal::EndpointIPtr> expand() const; + virtual std::vector<IceInternal::EndpointIPtr> expandIfWildcard() const; + virtual std::vector<IceInternal::EndpointIPtr> expandHost(IceInternal::EndpointIPtr&) const; virtual bool equivalent(const IceInternal::EndpointIPtr&) const; // From TestEndpoint diff --git a/csharp/src/Ice/ConnectionFactory.cs b/csharp/src/Ice/ConnectionFactory.cs index 8f695852f23..308be80e6c0 100644 --- a/csharp/src/Ice/ConnectionFactory.cs +++ b/csharp/src/Ice/ConnectionFactory.cs @@ -1265,10 +1265,28 @@ namespace IceInternal } } + public bool isLocal(EndpointI endpoint) + { + if(_publishedEndpoint != null && endpoint.equivalent(_publishedEndpoint)) + { + return true; + } + lock(this) + { + return endpoint.equivalent(_endpoint); + } + } + public EndpointI endpoint() { - // No mutex protection necessary, _endpoint is immutable. - return _endpoint; + if(_publishedEndpoint != null) + { + return _publishedEndpoint; + } + lock(this) + { + return _endpoint; + } } public ICollection<Ice.ConnectionI> connections() @@ -1528,10 +1546,12 @@ namespace IceInternal } } - public IncomingConnectionFactory(Instance instance, EndpointI endpoint, Ice.ObjectAdapterI adapter) + public IncomingConnectionFactory(Instance instance, EndpointI endpoint, EndpointI publish, + Ice.ObjectAdapterI adapter) { _instance = instance; _endpoint = endpoint; + _publishedEndpoint = publish; _adapter = adapter; _warn = _instance.initializationData().properties.getPropertyAsInt("Ice.Warn.Connections") > 0; _connections = new HashSet<Ice.ConnectionI>(); @@ -1788,6 +1808,7 @@ namespace IceInternal private Acceptor _acceptor; private readonly Transceiver _transceiver; private EndpointI _endpoint; + private readonly EndpointI _publishedEndpoint; private Ice.ObjectAdapterI _adapter; diff --git a/csharp/src/Ice/EndpointI.cs b/csharp/src/Ice/EndpointI.cs index 8d1e8aeb60a..6ba4b8e6621 100644 --- a/csharp/src/Ice/EndpointI.cs +++ b/csharp/src/Ice/EndpointI.cs @@ -146,7 +146,18 @@ namespace IceInternal // host if listening on INADDR_ANY on server side or if no host // was specified on client side. // - public abstract List<EndpointI> expand(); + public abstract List<EndpointI> expandIfWildcard(); + + // + // Expand endpoint out into separate endpoints for each IP + // address returned by the DNS resolver. Also returns the + // endpoint which can be used to connect to the returned + // endpoints or null if no specific endpoint can be used to + // connect to these endpoints (e.g.: with the IP endpoint, + // it returns this endpoint if it uses a fixed port, null + // otherwise). + // + public abstract List<EndpointI> expandHost(out EndpointI publishedEndpoint); // // Check whether the endpoint is equivalent to another one. diff --git a/csharp/src/Ice/IPEndpointI.cs b/csharp/src/Ice/IPEndpointI.cs index 16fa7944a27..b7a7186a35f 100644 --- a/csharp/src/Ice/IPEndpointI.cs +++ b/csharp/src/Ice/IPEndpointI.cs @@ -116,7 +116,7 @@ namespace IceInternal instance_.resolve(host_, port_, selType, this, callback); } - public override List<EndpointI> expand() + public override List<EndpointI> expandIfWildcard() { List<EndpointI> endps = new List<EndpointI>(); List<string> hosts = Network.getHostsForEndpointExpand(host_, instance_.protocolSupport(), false); @@ -134,6 +134,50 @@ namespace IceInternal return endps; } + public override List<EndpointI> expandHost(out EndpointI publish) + { + // + // If this endpoint has an empty host (wildcard address), don't expand, just return + // this endpoint. + // + var endpoints = new List<EndpointI>(); + if(host_.Length == 0) + { + publish = null; + endpoints.Add(this); + return endpoints; + } + + // + // If using a fixed port, this endpoint can be used as the published endpoint to + // access the returned endpoints. Otherwise, we'll publish each individual expanded + // endpoint. + // + publish = port_ > 0 ? this : null; + + List<EndPoint> addresses = Network.getAddresses(host_, + port_, + instance_.protocolSupport(), + Ice.EndpointSelectionType.Ordered, + instance_.preferIPv6(), + true); + + if(addresses.Count == 1) + { + endpoints.Add(this); + } + else + { + foreach(EndPoint addr in addresses) + { + endpoints.Add(createEndpoint(Network.endpointAddressToString(addr), + Network.endpointPort(addr), + connectionId_)); + } + } + return endpoints; + } + public override bool equivalent(EndpointI endpoint) { if(!(endpoint is IPEndpointI)) diff --git a/csharp/src/Ice/ObjectAdapterI.cs b/csharp/src/Ice/ObjectAdapterI.cs index a0f75b109ab..38891e49bf8 100644 --- a/csharp/src/Ice/ObjectAdapterI.cs +++ b/csharp/src/Ice/ObjectAdapterI.cs @@ -698,7 +698,7 @@ namespace Ice } foreach(IncomingConnectionFactory factory in _incomingConnectionFactories) { - if(endpoints[i].equivalent(factory.endpoint())) + if(factory.isLocal(endpoints[i])) { return true; } @@ -1022,8 +1022,15 @@ namespace Ice List<EndpointI> endpoints = parseEndpoints(properties.getProperty(_name + ".Endpoints"), true); foreach(EndpointI endp in endpoints) { - IncomingConnectionFactory factory = new IncomingConnectionFactory(instance, endp, this); - _incomingConnectionFactories.Add(factory); + EndpointI publishedEndpoint; + foreach(IceInternal.EndpointI expanded in endp.expandHost(out publishedEndpoint)) + { + IncomingConnectionFactory factory = new IncomingConnectionFactory(instance, + expanded, + publishedEndpoint, + this); + _incomingConnectionFactories.Add(factory); + } } if(endpoints.Count == 0) { @@ -1245,7 +1252,18 @@ namespace Ice // foreach(IncomingConnectionFactory factory in _incomingConnectionFactories) { - endpoints.AddRange(factory.endpoint().expand()); + foreach(EndpointI endpt in factory.endpoint().expandIfWildcard()) + { + // + // Check for duplicate endpoints, this might occur if an endpoint with a DNS name + // expands to multiple addresses. In this case, multiple incoming connection + // factories can point to the same published endpoint. + // + if(!endpoints.Contains(endpt)) + { + endpoints.Add(endpt); + } + } } } diff --git a/csharp/src/Ice/OpaqueEndpointI.cs b/csharp/src/Ice/OpaqueEndpointI.cs index 2421d75c68c..c52cc9c0185 100644 --- a/csharp/src/Ice/OpaqueEndpointI.cs +++ b/csharp/src/Ice/OpaqueEndpointI.cs @@ -227,13 +227,21 @@ namespace IceInternal // host if listening on INADDR_ANY on server side or if no host // was specified on client side. // - public override List<EndpointI> expand() + public override List<EndpointI> expandIfWildcard() { List<EndpointI> endps = new List<EndpointI>(); endps.Add(this); return endps; } + public override List<EndpointI> expandHost(out EndpointI publishedEndpoint) + { + publishedEndpoint = null; + List<EndpointI> endps = new List<EndpointI>(); + endps.Add(this); + return endps; + } + // // Check whether the endpoint is equivalent to another one. // @@ -384,7 +392,7 @@ namespace IceInternal { throw new Ice.EndpointParseException("Invalid Base64 input in endpoint " + endpoint, ex); } - + return true; } diff --git a/csharp/src/Ice/WSEndpoint.cs b/csharp/src/Ice/WSEndpoint.cs index d4e1e044732..7990f7ca224 100644 --- a/csharp/src/Ice/WSEndpoint.cs +++ b/csharp/src/Ice/WSEndpoint.cs @@ -215,17 +215,30 @@ namespace IceInternal return new WSEndpoint(_instance, delEndp, _resource); } - public override List<EndpointI> expand() + public override List<EndpointI> expandIfWildcard() { - List<EndpointI> endps = _delegate.expand(); List<EndpointI> l = new List<EndpointI>(); - foreach(EndpointI e in endps) + foreach(EndpointI e in _delegate.expandIfWildcard()) { l.Add(e == _delegate ? this : new WSEndpoint(_instance, e, _resource)); } return l; } + public override List<EndpointI> expandHost(out EndpointI publish) + { + List<EndpointI> l = new List<EndpointI>(); + foreach(EndpointI e in _delegate.expandHost(out publish)) + { + l.Add(e == _delegate ? this : new WSEndpoint(_instance, e, _resource)); + } + if(publish != null) + { + publish = publish == _delegate ? this : new WSEndpoint(_instance, publish, _resource); + } + return l; + } + public override bool equivalent(EndpointI endpoint) { if(!(endpoint is WSEndpoint)) @@ -274,7 +287,7 @@ namespace IceInternal public override int CompareTo(EndpointI obj) { - if(!(obj is EndpointI)) + if(!(obj is WSEndpoint)) { return type() < obj.type() ? -1 : 1; } diff --git a/csharp/src/IceSSL/EndpointI.cs b/csharp/src/IceSSL/EndpointI.cs index 52bf89e712f..f9b83efc211 100644 --- a/csharp/src/IceSSL/EndpointI.cs +++ b/csharp/src/IceSSL/EndpointI.cs @@ -188,16 +188,30 @@ namespace IceSSL return new EndpointI(_instance, del); } - public override List<IceInternal.EndpointI> expand() + public override List<IceInternal.EndpointI> expandIfWildcard() { List<IceInternal.EndpointI> l = new List<IceInternal.EndpointI>(); - foreach(IceInternal.EndpointI e in _delegate.expand()) + foreach(IceInternal.EndpointI e in _delegate.expandIfWildcard()) { l.Add(e == _delegate ? this : new EndpointI(_instance, e)); } return l; } + public override List<IceInternal.EndpointI> expandHost(out IceInternal.EndpointI publish) + { + List<IceInternal.EndpointI> l = new List<IceInternal.EndpointI>(); + foreach(IceInternal.EndpointI e in _delegate.expandHost(out publish)) + { + l.Add(e == _delegate ? this : new EndpointI(_instance, e)); + } + if(publish != null) + { + publish = publish == _delegate ? this : new EndpointI(_instance, publish); + } + return l; + } + public override bool equivalent(IceInternal.EndpointI endpoint) { if(!(endpoint is EndpointI)) diff --git a/csharp/test/Ice/background/EndpointI.cs b/csharp/test/Ice/background/EndpointI.cs index 277acd675ee..c77a748273a 100644 --- a/csharp/test/Ice/background/EndpointI.cs +++ b/csharp/test/Ice/background/EndpointI.cs @@ -171,16 +171,30 @@ internal class EndpointI : IceInternal.EndpointI return new EndpointI(delEndp); } - public override List<IceInternal.EndpointI> expand() + public override List<IceInternal.EndpointI> expandIfWildcard() { List<IceInternal.EndpointI> endps = new List<IceInternal.EndpointI>(); - foreach(IceInternal.EndpointI endpt in _endpoint.expand()) + foreach(IceInternal.EndpointI endpt in _endpoint.expandIfWildcard()) { endps.Add(endpt == _endpoint ? this : new EndpointI(endpt)); } return endps; } + public override List<IceInternal.EndpointI> expandHost(out IceInternal.EndpointI publish) + { + List<IceInternal.EndpointI> endps = new List<IceInternal.EndpointI>(); + foreach(IceInternal.EndpointI endpt in _endpoint.expandHost(out publish)) + { + endps.Add(endpt == _endpoint ? this : new EndpointI(endpt)); + } + if(publish != null) + { + publish = publish == _endpoint ? this : new EndpointI(publish); + } + return endps; + } + public override bool equivalent(IceInternal.EndpointI endpoint) { EndpointI testEndpoint = null; diff --git a/java-compat/src/Ice/src/main/java/Ice/ObjectAdapterI.java b/java-compat/src/Ice/src/main/java/Ice/ObjectAdapterI.java index 4b677da2c96..2e817cf9bff 100644 --- a/java-compat/src/Ice/src/main/java/Ice/ObjectAdapterI.java +++ b/java-compat/src/Ice/src/main/java/Ice/ObjectAdapterI.java @@ -755,7 +755,7 @@ public final class ObjectAdapterI implements ObjectAdapter } for(IncomingConnectionFactory p : _incomingConnectionFactories) { - if(endpoint.equivalent(p.endpoint())) + if(p.isLocal(endpoint)) { return true; } @@ -1079,8 +1079,15 @@ public final class ObjectAdapterI implements ObjectAdapter parseEndpoints(properties.getProperty(_name + ".Endpoints"), true); for(IceInternal.EndpointI endp : endpoints) { - IncomingConnectionFactory factory = new IncomingConnectionFactory(instance, endp, this); - _incomingConnectionFactories.add(factory); + Ice.Holder<IceInternal.EndpointI> publishedEndpoint = new Ice.Holder<>(); + for(IceInternal.EndpointI expanded : endp.expandHost(publishedEndpoint)) + { + IncomingConnectionFactory factory = new IncomingConnectionFactory(instance, + expanded, + publishedEndpoint.value, + this); + _incomingConnectionFactories.add(factory); + } } if(endpoints.size() == 0) { @@ -1339,7 +1346,18 @@ public final class ObjectAdapterI implements ObjectAdapter // for(IncomingConnectionFactory factory : _incomingConnectionFactories) { - endpoints.addAll(factory.endpoint().expand()); + for(IceInternal.EndpointI endpt : factory.endpoint().expandIfWildcard()) + { + // + // Check for duplicate endpoints, this might occur if an endpoint with a DNS name + // expands to multiple addresses. In this case, multiple incoming connection + // factories can point to the same published endpoint. + // + if(!endpoints.contains(endpt)) + { + endpoints.add(endpt); + } + } } } diff --git a/java-compat/src/Ice/src/main/java/IceInternal/EndpointI.java b/java-compat/src/Ice/src/main/java/IceInternal/EndpointI.java index b6ce248e5d4..700d4f8b71d 100644 --- a/java-compat/src/Ice/src/main/java/IceInternal/EndpointI.java +++ b/java-compat/src/Ice/src/main/java/IceInternal/EndpointI.java @@ -120,7 +120,18 @@ abstract public class EndpointI implements Ice.Endpoint, java.lang.Comparable<En // Expand endpoint out in to separate endpoints for each local // host if listening on INADDR_ANY. // - public abstract java.util.List<EndpointI> expand(); + public abstract java.util.List<EndpointI> expandIfWildcard(); + + // + // Expand endpoint out into separate endpoints for each IP + // address returned by the DNS resolver. Also returns the + // endpoint which can be used to connect to the returned + // endpoints or null if no specific endpoint can be used to + // connect to these endpoints (e.g.: with the IP endpoint, + // it returns this endpoint if it uses a fixed port, null + // otherwise). + // + public abstract java.util.List<EndpointI> expandHost(Ice.Holder<EndpointI> publishedEndpoint); // // Check whether the endpoint is equivalent to another one. diff --git a/java-compat/src/Ice/src/main/java/IceInternal/IPEndpointI.java b/java-compat/src/Ice/src/main/java/IceInternal/IPEndpointI.java index cbdeebe8a66..e67a02ff611 100644 --- a/java-compat/src/Ice/src/main/java/IceInternal/IPEndpointI.java +++ b/java-compat/src/Ice/src/main/java/IceInternal/IPEndpointI.java @@ -113,7 +113,7 @@ public abstract class IPEndpointI extends EndpointI } @Override - public java.util.List<EndpointI> expand() + public java.util.List<EndpointI> expandIfWildcard() { java.util.List<EndpointI> endps = new java.util.ArrayList<EndpointI>(); java.util.List<String> hosts = Network.getHostsForEndpointExpand(_host, _instance.protocolSupport(), false); @@ -132,6 +132,50 @@ public abstract class IPEndpointI extends EndpointI } @Override + public java.util.List<EndpointI> expandHost(Ice.Holder<EndpointI> publishedEndpoint) + { + // + // If this endpoint has an empty host (wildcard address), don't expand, just return + // this endpoint. + // + if(_host.isEmpty()) + { + java.util.ArrayList<EndpointI> endpoints = new java.util.ArrayList<>(); + endpoints.add(this); + return endpoints; + } + + // + // If using a fixed port, this endpoint can be used as the published endpoint to + // access the returned endpoints. Otherwise, we'll publish each individual expanded + // endpoint. + // + publishedEndpoint.value = _port > 0 ? this : null; + + java.util.List<java.net.InetSocketAddress> addresses = Network.getAddresses(_host, + _port, + _instance.protocolSupport(), + Ice.EndpointSelectionType.Ordered, + _instance.preferIPv6(), + true); + + + java.util.ArrayList<EndpointI> endpoints = new java.util.ArrayList<>(); + if(addresses.size() == 1) + { + endpoints.add(this); + } + else + { + for(java.net.InetSocketAddress addr : addresses) + { + endpoints.add(createEndpoint(addr.getAddress().getHostAddress(), addr.getPort(), _connectionId)); + } + } + return endpoints; + } + + @Override public boolean equivalent(EndpointI endpoint) { if(!(endpoint instanceof IPEndpointI)) diff --git a/java-compat/src/Ice/src/main/java/IceInternal/IncomingConnectionFactory.java b/java-compat/src/Ice/src/main/java/IceInternal/IncomingConnectionFactory.java index 1e031a86cde..9d830960d75 100644 --- a/java-compat/src/Ice/src/main/java/IceInternal/IncomingConnectionFactory.java +++ b/java-compat/src/Ice/src/main/java/IceInternal/IncomingConnectionFactory.java @@ -169,11 +169,30 @@ public final class IncomingConnectionFactory extends EventHandler implements Ice } } + public boolean + isLocal(EndpointI endpoint) + { + if(_publishedEndpoint != null && endpoint.equivalent(_publishedEndpoint)) + { + return true; + } + synchronized(this) + { + return endpoint.equivalent(_endpoint); + } + } + public EndpointI endpoint() { - // No mutex protection necessary, _endpoint is immutable. - return _endpoint; + if(_publishedEndpoint != null) + { + return _publishedEndpoint; + } + synchronized(this) + { + return _endpoint; + } } public synchronized java.util.LinkedList<Ice.ConnectionI> @@ -420,10 +439,11 @@ public final class IncomingConnectionFactory extends EventHandler implements Ice } public - IncomingConnectionFactory(Instance instance, EndpointI endpoint, Ice.ObjectAdapterI adapter) + IncomingConnectionFactory(Instance instance, EndpointI endpoint, EndpointI publish, Ice.ObjectAdapterI adapter) { _instance = instance; _endpoint = endpoint; + _publishedEndpoint = publish; _adapter = adapter; _warn = _instance.initializationData().properties.getPropertyAsInt("Ice.Warn.Connections") > 0 ? true : false; _state = StateHolding; @@ -718,6 +738,7 @@ public final class IncomingConnectionFactory extends EventHandler implements Ice private Acceptor _acceptor; private Transceiver _transceiver; private EndpointI _endpoint; + private final EndpointI _publishedEndpoint; private Ice.ObjectAdapterI _adapter; diff --git a/java-compat/src/Ice/src/main/java/IceInternal/OpaqueEndpointI.java b/java-compat/src/Ice/src/main/java/IceInternal/OpaqueEndpointI.java index aea8308a636..85bf2473ee7 100644 --- a/java-compat/src/Ice/src/main/java/IceInternal/OpaqueEndpointI.java +++ b/java-compat/src/Ice/src/main/java/IceInternal/OpaqueEndpointI.java @@ -215,9 +215,18 @@ final class OpaqueEndpointI extends EndpointI // was specified on client side. // @Override - public java.util.List<EndpointI> expand() + public java.util.List<EndpointI> expandIfWildcard() { - java.util.List<EndpointI> endps = new java.util.ArrayList<EndpointI>(); + java.util.List<EndpointI> endps = new java.util.ArrayList<>(); + endps.add(this); + return endps; + } + + @Override + public java.util.List<EndpointI> expandHost(Ice.Holder<EndpointI> publish) + { + publish.value = null; + java.util.List<EndpointI> endps = new java.util.ArrayList<>(); endps.add(this); return endps; } diff --git a/java-compat/src/Ice/src/main/java/IceInternal/WSEndpoint.java b/java-compat/src/Ice/src/main/java/IceInternal/WSEndpoint.java index 2cba87138b9..ad4c70cd973 100644 --- a/java-compat/src/Ice/src/main/java/IceInternal/WSEndpoint.java +++ b/java-compat/src/Ice/src/main/java/IceInternal/WSEndpoint.java @@ -207,11 +207,10 @@ final class WSEndpoint extends IceInternal.EndpointI } @Override - public java.util.List<EndpointI> expand() + public java.util.List<EndpointI> expandIfWildcard() { - java.util.List<EndpointI> endps = _delegate.expand(); java.util.List<EndpointI> l = new java.util.ArrayList<EndpointI>(); - for(EndpointI e : endps) + for(EndpointI e : _delegate.expandIfWildcard()) { l.add(e == _delegate ? this : new WSEndpoint(_instance, e, _resource)); } @@ -219,6 +218,21 @@ final class WSEndpoint extends IceInternal.EndpointI } @Override + public java.util.List<EndpointI> expandHost(Ice.Holder<EndpointI> publish) + { + java.util.List<EndpointI> l = new java.util.ArrayList<EndpointI>(); + for(EndpointI e : _delegate.expandHost(publish)) + { + l.add(e == _delegate ? this : new WSEndpoint(_instance, e, _resource)); + } + if(publish.value != null) + { + publish.value = publish.value == _delegate ? this : new WSEndpoint(_instance, publish.value, _resource); + } + return l; + } + + @Override public boolean equivalent(EndpointI endpoint) { if(!(endpoint instanceof WSEndpoint)) diff --git a/java-compat/src/Ice/src/main/java/IceSSL/EndpointI.java b/java-compat/src/Ice/src/main/java/IceSSL/EndpointI.java index cda60997e7b..e5f9854bb76 100644 --- a/java-compat/src/Ice/src/main/java/IceSSL/EndpointI.java +++ b/java-compat/src/Ice/src/main/java/IceSSL/EndpointI.java @@ -195,11 +195,10 @@ final class EndpointI extends IceInternal.EndpointI } @Override - public java.util.List<IceInternal.EndpointI> expand() + public java.util.List<IceInternal.EndpointI> expandIfWildcard() { - java.util.List<IceInternal.EndpointI> endps = _delegate.expand(); java.util.List<IceInternal.EndpointI> l = new java.util.ArrayList<IceInternal.EndpointI>(); - for(IceInternal.EndpointI e : endps) + for(IceInternal.EndpointI e : _delegate.expandIfWildcard()) { l.add(e == _delegate ? this : new EndpointI(_instance, e)); } @@ -207,6 +206,21 @@ final class EndpointI extends IceInternal.EndpointI } @Override + public java.util.List<IceInternal.EndpointI> expandHost(Ice.Holder<IceInternal.EndpointI> publish) + { + java.util.List<IceInternal.EndpointI> l = new java.util.ArrayList<IceInternal.EndpointI>(); + for(IceInternal.EndpointI e : _delegate.expandHost(publish)) + { + l.add(e == _delegate ? this : new EndpointI(_instance, e)); + } + if(publish.value != null) + { + publish.value = publish.value == _delegate ? this : new EndpointI(_instance, publish.value); + } + return l; + } + + @Override public boolean equivalent(IceInternal.EndpointI endpoint) { if(!(endpoint instanceof EndpointI)) diff --git a/java-compat/src/IceBT/src/main/java/IceBT/EndpointI.java b/java-compat/src/IceBT/src/main/java/IceBT/EndpointI.java index cbb3cf4c6dc..28df16fdf46 100644 --- a/java-compat/src/IceBT/src/main/java/IceBT/EndpointI.java +++ b/java-compat/src/IceBT/src/main/java/IceBT/EndpointI.java @@ -184,7 +184,7 @@ final class EndpointI extends IceInternal.EndpointI } @Override - public java.util.List<IceInternal.EndpointI> expand() + public java.util.List<IceInternal.EndpointI> expandIfWildcard() { java.util.List<IceInternal.EndpointI> endps = new java.util.ArrayList<IceInternal.EndpointI>(); endps.add(this); @@ -192,6 +192,15 @@ final class EndpointI extends IceInternal.EndpointI } @Override + public java.util.List<IceInternal.EndpointI> expandHost(Ice.Holder<IceInternal.EndpointI> publish) + { + publish.value = null; + java.util.List<IceInternal.EndpointI> endps = new java.util.ArrayList<IceInternal.EndpointI>(); + endps.add(this); + return endps; + } + + @Override public boolean equivalent(IceInternal.EndpointI endpoint) { if(!(endpoint instanceof EndpointI)) diff --git a/java-compat/test/src/main/java/test/Ice/background/EndpointI.java b/java-compat/test/src/main/java/test/Ice/background/EndpointI.java index f0508bcf91e..ef8a6449966 100644 --- a/java-compat/test/src/main/java/test/Ice/background/EndpointI.java +++ b/java-compat/test/src/main/java/test/Ice/background/EndpointI.java @@ -201,11 +201,10 @@ final class EndpointI extends IceInternal.EndpointI } @Override - public java.util.List<IceInternal.EndpointI> - expand() + public java.util.List<IceInternal.EndpointI> expandIfWildcard() { java.util.List<IceInternal.EndpointI> endps = new java.util.ArrayList<IceInternal.EndpointI>(); - for(IceInternal.EndpointI endpt : _endpoint.expand()) + for(IceInternal.EndpointI endpt : _endpoint.expandIfWildcard()) { endps.add(endpt == _endpoint ? this : new EndpointI(_configuration, endpt)); } @@ -213,6 +212,21 @@ final class EndpointI extends IceInternal.EndpointI } @Override + public java.util.List<IceInternal.EndpointI> expandHost(Ice.Holder<IceInternal.EndpointI> publish) + { + java.util.List<IceInternal.EndpointI> endps = new java.util.ArrayList<IceInternal.EndpointI>(); + for(IceInternal.EndpointI endpt : _endpoint.expandHost(publish)) + { + endps.add(endpt == _endpoint ? this : new EndpointI(_configuration, endpt)); + } + if(publish.value != null) + { + publish.value = publish.value == _endpoint ? this : new EndpointI(_configuration, publish.value); + } + return endps; + } + + @Override public boolean equivalent(IceInternal.EndpointI endpoint) { diff --git a/java/src/Ice/src/main/java/com/zeroc/Ice/ObjectAdapterI.java b/java/src/Ice/src/main/java/com/zeroc/Ice/ObjectAdapterI.java index 6a8103283b5..3b9dfd5343f 100644 --- a/java/src/Ice/src/main/java/com/zeroc/Ice/ObjectAdapterI.java +++ b/java/src/Ice/src/main/java/com/zeroc/Ice/ObjectAdapterI.java @@ -14,6 +14,7 @@ import java.util.List; import java.util.ArrayList; import com.zeroc.IceInternal.IncomingConnectionFactory; +import com.zeroc.IceInternal.EndpointI; public final class ObjectAdapterI implements ObjectAdapter { @@ -754,7 +755,7 @@ public final class ObjectAdapterI implements ObjectAdapter } for(IncomingConnectionFactory p : _incomingConnectionFactories) { - if(endpoint.equivalent(p.endpoint())) + if(p.isLocal(endpoint)) { return true; } @@ -1075,14 +1076,21 @@ public final class ObjectAdapterI implements ObjectAdapter // Parse the endpoints, but don't store them in the adapter. The connection // factory might change it, for example, to fill in the real port number. // - List<com.zeroc.IceInternal.EndpointI> endpoints = - parseEndpoints(properties.getProperty(_name + ".Endpoints"), true); - for(com.zeroc.IceInternal.EndpointI endp : endpoints) + List<EndpointI> endpoints = parseEndpoints(properties.getProperty(_name + ".Endpoints"), true); + for(EndpointI endp : endpoints) { - IncomingConnectionFactory factory = new IncomingConnectionFactory(instance, endp, this); - _incomingConnectionFactories.add(factory); + EndpointI.ExpandHostResult result = endp.expandHost(); + for(EndpointI expanded : result.endpoints) + { + + IncomingConnectionFactory factory = new IncomingConnectionFactory(instance, + expanded, + result.publish, + this); + _incomingConnectionFactories.add(factory); + } } - if(endpoints.size() == 0) + if(endpoints.isEmpty()) { com.zeroc.IceInternal.TraceLevels tl = _instance.traceLevels(); if(tl.network >= 2) @@ -1338,7 +1346,18 @@ public final class ObjectAdapterI implements ObjectAdapter // for(IncomingConnectionFactory factory : _incomingConnectionFactories) { - endpoints.addAll(factory.endpoint().expand()); + for(EndpointI endpt : factory.endpoint().expandIfWildcard()) + { + // + // Check for duplicate endpoints, this might occur if an endpoint with a DNS name + // expands to multiple addresses. In this case, multiple incoming connection + // factories can point to the same published endpoint. + // + if(!endpoints.contains(endpt)) + { + endpoints.add(endpt); + } + } } } diff --git a/java/src/Ice/src/main/java/com/zeroc/IceInternal/EndpointI.java b/java/src/Ice/src/main/java/com/zeroc/IceInternal/EndpointI.java index f0c0c353f26..824a1849e70 100644 --- a/java/src/Ice/src/main/java/com/zeroc/IceInternal/EndpointI.java +++ b/java/src/Ice/src/main/java/com/zeroc/IceInternal/EndpointI.java @@ -11,6 +11,12 @@ package com.zeroc.IceInternal; abstract public class EndpointI implements com.zeroc.Ice.Endpoint, java.lang.Comparable<EndpointI> { + public class ExpandHostResult + { + public EndpointI publish; + public java.util.List<EndpointI> endpoints; + }; + public void streamWrite(com.zeroc.Ice.OutputStream s) { s.startEncapsulation(); @@ -120,7 +126,18 @@ abstract public class EndpointI implements com.zeroc.Ice.Endpoint, java.lang.Com // Expand endpoint out in to separate endpoints for each local // host if listening on INADDR_ANY. // - public abstract java.util.List<EndpointI> expand(); + public abstract java.util.List<EndpointI> expandIfWildcard(); + + // + // Expand endpoint out into separate endpoints for each IP + // address returned by the DNS resolver. Also returns the + // endpoint which can be used to connect to the returned + // endpoints or null if no specific endpoint can be used to + // connect to these endpoints (e.g.: with the IP endpoint, + // it returns this endpoint if it uses a fixed port, null + // otherwise). + // + public abstract ExpandHostResult expandHost(); // // Check whether the endpoint is equivalent to another one. diff --git a/java/src/Ice/src/main/java/com/zeroc/IceInternal/IPEndpointI.java b/java/src/Ice/src/main/java/com/zeroc/IceInternal/IPEndpointI.java index c9d01736d7f..53d1d4fad64 100644 --- a/java/src/Ice/src/main/java/com/zeroc/IceInternal/IPEndpointI.java +++ b/java/src/Ice/src/main/java/com/zeroc/IceInternal/IPEndpointI.java @@ -9,6 +9,8 @@ package com.zeroc.IceInternal; +import com.zeroc.Ice.EndpointSelectionType; + public abstract class IPEndpointI extends EndpointI { protected IPEndpointI(ProtocolInstance instance, String host, int port, java.net.InetSocketAddress sourceAddr, @@ -113,7 +115,7 @@ public abstract class IPEndpointI extends EndpointI } @Override - public java.util.List<EndpointI> expand() + public java.util.List<EndpointI> expandIfWildcard() { java.util.List<EndpointI> endps = new java.util.ArrayList<>(); java.util.List<String> hosts = Network.getHostsForEndpointExpand(_host, _instance.protocolSupport(), false); @@ -132,6 +134,51 @@ public abstract class IPEndpointI extends EndpointI } @Override + public EndpointI.ExpandHostResult expandHost() + { + EndpointI.ExpandHostResult result = new EndpointI.ExpandHostResult(); + + // + // If this endpoint has an empty host (wildcard address), don't expand, just return + // this endpoint. + // + if(_host.isEmpty()) + { + result.endpoints = new java.util.ArrayList<>(); + result.endpoints.add(this); + return result; + } + + // + // If using a fixed port, this endpoint can be used as the published endpoint to + // access the returned endpoints. Otherwise, we'll publish each individual expanded + // endpoint. + // + result.publish = _port > 0 ? this : null; + + java.util.List<java.net.InetSocketAddress> addresses = Network.getAddresses(_host, + _port, + _instance.protocolSupport(), + EndpointSelectionType.Ordered, + _instance.preferIPv6(), + true); + + result.endpoints = new java.util.ArrayList<>(); + if(addresses.size() == 1) + { + result.endpoints.add(this); + } + else + { + for(java.net.InetSocketAddress addr : addresses) + { + result.endpoints.add(createEndpoint(addr.getAddress().getHostAddress(), addr.getPort(), _connectionId)); + } + } + return result; + } + + @Override public boolean equivalent(EndpointI endpoint) { if(!(endpoint instanceof IPEndpointI)) diff --git a/java/src/Ice/src/main/java/com/zeroc/IceInternal/IncomingConnectionFactory.java b/java/src/Ice/src/main/java/com/zeroc/IceInternal/IncomingConnectionFactory.java index cd534fa7523..806d4ed9887 100644 --- a/java/src/Ice/src/main/java/com/zeroc/IceInternal/IncomingConnectionFactory.java +++ b/java/src/Ice/src/main/java/com/zeroc/IceInternal/IncomingConnectionFactory.java @@ -165,11 +165,30 @@ public final class IncomingConnectionFactory extends EventHandler implements Con } } + public boolean + isLocal(EndpointI endpoint) + { + if(_publishedEndpoint != null && endpoint.equivalent(_publishedEndpoint)) + { + return true; + } + synchronized(this) + { + return endpoint.equivalent(_endpoint); + } + } + public EndpointI endpoint() { - // No mutex protection necessary, _endpoint is immutable. - return _endpoint; + if(_publishedEndpoint != null) + { + return _publishedEndpoint; + } + synchronized(this) + { + return _endpoint; + } } public synchronized java.util.LinkedList<ConnectionI> @@ -416,10 +435,12 @@ public final class IncomingConnectionFactory extends EventHandler implements Con } public - IncomingConnectionFactory(Instance instance, EndpointI endpoint, com.zeroc.Ice.ObjectAdapterI adapter) + IncomingConnectionFactory(Instance instance, EndpointI endpoint, EndpointI publish, + com.zeroc.Ice.ObjectAdapterI adapter) { _instance = instance; _endpoint = endpoint; + _publishedEndpoint = publish; _adapter = adapter; _warn = _instance.initializationData().properties.getPropertyAsInt("Ice.Warn.Connections") > 0 ? true : false; _state = StateHolding; @@ -708,6 +729,7 @@ public final class IncomingConnectionFactory extends EventHandler implements Con private Acceptor _acceptor; private Transceiver _transceiver; private EndpointI _endpoint; + private final EndpointI _publishedEndpoint; private com.zeroc.Ice.ObjectAdapterI _adapter; diff --git a/java/src/Ice/src/main/java/com/zeroc/IceInternal/OpaqueEndpointI.java b/java/src/Ice/src/main/java/com/zeroc/IceInternal/OpaqueEndpointI.java index e4dd3fec957..2c842ddd77c 100644 --- a/java/src/Ice/src/main/java/com/zeroc/IceInternal/OpaqueEndpointI.java +++ b/java/src/Ice/src/main/java/com/zeroc/IceInternal/OpaqueEndpointI.java @@ -218,13 +218,22 @@ final class OpaqueEndpointI extends EndpointI // was specified on client side. // @Override - public java.util.List<EndpointI> expand() + public java.util.List<EndpointI> expandIfWildcard() { java.util.List<EndpointI> endps = new java.util.ArrayList<>(); endps.add(this); return endps; } + @Override + public EndpointI.ExpandHostResult expandHost() + { + EndpointI.ExpandHostResult result = new EndpointI.ExpandHostResult(); + result.endpoints = new java.util.ArrayList<>(); + result.endpoints.add(this); + return result; + } + // // Check whether the endpoint is equivalent to another one. // diff --git a/java/src/Ice/src/main/java/com/zeroc/IceInternal/WSEndpoint.java b/java/src/Ice/src/main/java/com/zeroc/IceInternal/WSEndpoint.java index 3334bf385c4..80ffeab3803 100644 --- a/java/src/Ice/src/main/java/com/zeroc/IceInternal/WSEndpoint.java +++ b/java/src/Ice/src/main/java/com/zeroc/IceInternal/WSEndpoint.java @@ -209,9 +209,9 @@ final class WSEndpoint extends EndpointI } @Override - public java.util.List<EndpointI> expand() + public java.util.List<EndpointI> expandIfWildcard() { - java.util.List<EndpointI> endps = _delegate.expand(); + java.util.List<EndpointI> endps = _delegate.expandIfWildcard(); java.util.List<EndpointI> l = new java.util.ArrayList<>(); for(EndpointI e : endps) { @@ -221,6 +221,23 @@ final class WSEndpoint extends EndpointI } @Override + public EndpointI.ExpandHostResult expandHost() + { + EndpointI.ExpandHostResult result = _delegate.expandHost(); + java.util.List<EndpointI> l = new java.util.ArrayList<>(); + for(EndpointI e : result.endpoints) + { + l.add(e == _delegate ? this : new WSEndpoint(_instance, e, _resource)); + } + result.endpoints = l; + if(result.publish != null) + { + result.publish = result.publish == _delegate ? this : new WSEndpoint(_instance, result.publish, _resource); + } + return result; + } + + @Override public boolean equivalent(EndpointI endpoint) { if(!(endpoint instanceof WSEndpoint)) diff --git a/java/src/IceBT/src/main/java/com/zeroc/IceBT/EndpointI.java b/java/src/IceBT/src/main/java/com/zeroc/IceBT/EndpointI.java index b57cc25368b..c6589932874 100644 --- a/java/src/IceBT/src/main/java/com/zeroc/IceBT/EndpointI.java +++ b/java/src/IceBT/src/main/java/com/zeroc/IceBT/EndpointI.java @@ -195,15 +195,23 @@ final class EndpointI extends com.zeroc.IceInternal.EndpointI } @Override - public java.util.List<com.zeroc.IceInternal.EndpointI> expand() + public java.util.List<com.zeroc.IceInternal.EndpointI> expandIfWildcard() { - java.util.List<com.zeroc.IceInternal.EndpointI> endps = - new java.util.ArrayList<com.zeroc.IceInternal.EndpointI>(); + java.util.List<com.zeroc.IceInternal.EndpointI> endps = new java.util.ArrayList<>(); endps.add(this); return endps; } @Override + public com.zeroc.IceInternal.EndpointI.ExpandHostResult expandHost() + { + com.zeroc.IceInternal.EndpointI.ExpandHostResult result = new com.zeroc.IceInternal.EndpointI.ExpandHostResult(); + result.endpoints = new java.util.ArrayList<>(); + result.endpoints.add(this); + return result; + } + + @Override public boolean equivalent(com.zeroc.IceInternal.EndpointI endpoint) { if(!(endpoint instanceof EndpointI)) diff --git a/java/src/IceSSL/src/main/java/com/zeroc/IceSSL/EndpointI.java b/java/src/IceSSL/src/main/java/com/zeroc/IceSSL/EndpointI.java index 6e88f00868b..bcad6368785 100644 --- a/java/src/IceSSL/src/main/java/com/zeroc/IceSSL/EndpointI.java +++ b/java/src/IceSSL/src/main/java/com/zeroc/IceSSL/EndpointI.java @@ -197,11 +197,10 @@ final class EndpointI extends com.zeroc.IceInternal.EndpointI } @Override - public java.util.List<com.zeroc.IceInternal.EndpointI> expand() + public java.util.List<com.zeroc.IceInternal.EndpointI> expandIfWildcard() { - java.util.List<com.zeroc.IceInternal.EndpointI> endps = _delegate.expand(); - java.util.List<com.zeroc.IceInternal.EndpointI> l = new java.util.ArrayList<com.zeroc.IceInternal.EndpointI>(); - for(com.zeroc.IceInternal.EndpointI e : endps) + java.util.List<com.zeroc.IceInternal.EndpointI> l = new java.util.ArrayList<>(); + for(com.zeroc.IceInternal.EndpointI e : _delegate.expandIfWildcard()) { l.add(e == _delegate ? this : new EndpointI(_instance, e)); } @@ -209,6 +208,23 @@ final class EndpointI extends com.zeroc.IceInternal.EndpointI } @Override + public com.zeroc.IceInternal.EndpointI.ExpandHostResult expandHost() + { + com.zeroc.IceInternal.EndpointI.ExpandHostResult result = _delegate.expandHost(); + java.util.List<com.zeroc.IceInternal.EndpointI> l = new java.util.ArrayList<>(); + for(com.zeroc.IceInternal.EndpointI e : result.endpoints) + { + l.add(e == _delegate ? this : new EndpointI(_instance, e)); + } + result.endpoints = l; + if(result.publish != null) + { + result.publish = result.publish == _delegate ? this : new EndpointI(_instance, result.publish); + } + return result; + } + + @Override public boolean equivalent(com.zeroc.IceInternal.EndpointI endpoint) { if(!(endpoint instanceof EndpointI)) diff --git a/java/test/src/main/java/test/Ice/background/EndpointI.java b/java/test/src/main/java/test/Ice/background/EndpointI.java index 9fb00074cc2..1e5f03cdf7c 100644 --- a/java/test/src/main/java/test/Ice/background/EndpointI.java +++ b/java/test/src/main/java/test/Ice/background/EndpointI.java @@ -184,11 +184,10 @@ final class EndpointI extends com.zeroc.IceInternal.EndpointI } @Override - public java.util.List<com.zeroc.IceInternal.EndpointI> expand() + public java.util.List<com.zeroc.IceInternal.EndpointI> expandIfWildcard() { - java.util.List<com.zeroc.IceInternal.EndpointI> endps = - new java.util.ArrayList<com.zeroc.IceInternal.EndpointI>(); - for(com.zeroc.IceInternal.EndpointI endpt : _endpoint.expand()) + java.util.List<com.zeroc.IceInternal.EndpointI> endps = new java.util.ArrayList<>(); + for(com.zeroc.IceInternal.EndpointI endpt : _endpoint.expandIfWildcard()) { endps.add(endpt == _endpoint ? this : new EndpointI(_configuration, endpt)); } @@ -196,6 +195,23 @@ final class EndpointI extends com.zeroc.IceInternal.EndpointI } @Override + public com.zeroc.IceInternal.EndpointI.ExpandHostResult expandHost() + { + com.zeroc.IceInternal.EndpointI.ExpandHostResult result = _endpoint.expandHost(); + java.util.List<com.zeroc.IceInternal.EndpointI> l = new java.util.ArrayList<>(); + for(com.zeroc.IceInternal.EndpointI e : result.endpoints) + { + l.add(e == _endpoint ? this : new EndpointI(_configuration, e)); + } + result.endpoints = l; + if(result.publish != null) + { + result.publish = result.publish == _endpoint ? this : new EndpointI(_configuration, result.publish); + } + return result; + } + + @Override public boolean equivalent(com.zeroc.IceInternal.EndpointI endpoint) { EndpointI testEndpoint = null; |