diff options
author | Benoit Foucher <benoit@zeroc.com> | 2017-03-01 19:42:52 +0100 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2017-03-01 19:42:52 +0100 |
commit | 0a57f0b1841f51bc45ff2adc9ac19e114d695e43 (patch) | |
tree | 2ecab85164a70618fc0f861058f97194cb4e797e /cpp/src | |
parent | UWP build failure (diff) | |
download | ice-0a57f0b1841f51bc45ff2adc9ac19e114d695e43.tar.bz2 ice-0a57f0b1841f51bc45ff2adc9ac19e114d695e43.tar.xz ice-0a57f0b1841f51bc45ff2adc9ac19e114d695e43.zip |
Fixed ICE-7584 - discovery plugins now send multicast datagrams on all interfaces
Diffstat (limited to 'cpp/src')
-rwxr-xr-x | cpp/src/Ice/Network.cpp | 10 | ||||
-rwxr-xr-x | cpp/src/Ice/Network.h | 2 | ||||
-rw-r--r-- | cpp/src/Ice/PropertyNames.cpp | 39 | ||||
-rw-r--r-- | cpp/src/Ice/PropertyNames.h | 2 | ||||
-rwxr-xr-x | cpp/src/Ice/UdpTransceiver.cpp | 2 | ||||
-rw-r--r-- | cpp/src/IceDiscovery/LookupI.cpp | 222 | ||||
-rw-r--r-- | cpp/src/IceDiscovery/LookupI.h | 3 | ||||
-rw-r--r-- | cpp/src/IceDiscovery/PluginI.cpp | 64 | ||||
-rw-r--r-- | cpp/src/IceGrid/Client.cpp | 158 | ||||
-rw-r--r-- | cpp/src/IceGrid/Makefile.mk | 5 | ||||
-rw-r--r-- | cpp/src/IceGrid/msbuild/icegridadmin/icegridadmin.vcxproj | 41 | ||||
-rw-r--r-- | cpp/src/IceGrid/msbuild/icegridadmin/icegridadmin.vcxproj.filters | 27 | ||||
-rw-r--r-- | cpp/src/IceLocatorDiscovery/Plugin.h | 52 | ||||
-rw-r--r-- | cpp/src/IceLocatorDiscovery/PluginI.cpp | 419 | ||||
-rw-r--r-- | cpp/src/IceLocatorDiscovery/PluginI.h | 36 |
15 files changed, 548 insertions, 534 deletions
diff --git a/cpp/src/Ice/Network.cpp b/cpp/src/Ice/Network.cpp index 05abc9528f9..b98ea329429 100755 --- a/cpp/src/Ice/Network.cpp +++ b/cpp/src/Ice/Network.cpp @@ -1664,9 +1664,8 @@ IceInternal::getHostsForEndpointExpand(const string& host, ProtocolSupport proto } vector<string> -IceInternal::getInterfacesForMulticast(const string& intf, const Address& mcastAddr) +IceInternal::getInterfacesForMulticast(const string& intf, ProtocolSupport protocolSupport) { - ProtocolSupport protocolSupport = getProtocolSupport(mcastAddr); vector<string> interfaces = getHostsForEndpointExpand(intf, protocolSupport, true); if(interfaces.empty()) { @@ -1700,9 +1699,8 @@ IceInternal::getHostsForEndpointExpand(const string& host, ProtocolSupport proto } vector<string> -IceInternal::getInterfacesForMulticast(const string& intf, const Address& mcastAddr) +IceInternal::getInterfacesForMulticast(const string& intf, ProtocolSupport protocolSupport) { - ProtocolSupport protocolSupport = getProtocolSupport(mcastAddr); vector<string> interfaces; bool ipv4Wildcard = false; if(isWildcard(intf, protocolSupport, ipv4Wildcard)) @@ -2069,7 +2067,7 @@ IceInternal::getRecvBufferSize(SOCKET fd) void IceInternal::setMcastGroup(SOCKET fd, const Address& group, const string& intf) { - vector<string> interfaces = getInterfacesForMulticast(intf, group); + vector<string> interfaces = getInterfacesForMulticast(intf, getProtocolSupport(group)); set<int> indexes; for(vector<string>::const_iterator p = interfaces.begin(); p != interfaces.end(); ++p) { @@ -3068,7 +3066,7 @@ IceInternal::isIpAddress(const string& name) #else in_addr addr; in6_addr addr6; - + return inet_pton(AF_INET, name.c_str(), &addr) > 0 || inet_pton(AF_INET6, name.c_str(), &addr6) > 0; #endif }
\ No newline at end of file diff --git a/cpp/src/Ice/Network.h b/cpp/src/Ice/Network.h index df07941f73d..38ae134437f 100755 --- a/cpp/src/Ice/Network.h +++ b/cpp/src/Ice/Network.h @@ -284,7 +284,7 @@ ICE_API std::string addressesToString(const Address&, const Address&, bool); ICE_API bool isAddressValid(const Address&); ICE_API std::vector<std::string> getHostsForEndpointExpand(const std::string&, ProtocolSupport, bool); -ICE_API std::vector<std::string> getInterfacesForMulticast(const std::string&, const Address&); +ICE_API std::vector<std::string> getInterfacesForMulticast(const std::string&, ProtocolSupport); ICE_API std::string inetAddrToString(const Address&); ICE_API int getPort(const Address&); diff --git a/cpp/src/Ice/PropertyNames.cpp b/cpp/src/Ice/PropertyNames.cpp index e78121014d3..02ee0f7ac2c 100644 --- a/cpp/src/Ice/PropertyNames.cpp +++ b/cpp/src/Ice/PropertyNames.cpp @@ -6,7 +6,7 @@ // ICE_LICENSE file included in this distribution. // // ********************************************************************** -// Generated by makeprops.py from file ..\config\PropertyNames.xml, Fri Feb 24 18:49:18 2017 +// Generated by makeprops.py from file ./config/PropertyNames.xml, Tue Feb 28 15:01:12 2017 // IMPORTANT: Do not edit this file -- any edits made here will be lost! @@ -520,6 +520,43 @@ const IceInternal::Property IceGridAdminPropsData[] = IceInternal::Property("IceGridAdmin.Discovery.Reply.ThreadPool.ThreadIdleTime", false, 0), IceInternal::Property("IceGridAdmin.Discovery.Reply.ThreadPool.ThreadPriority", false, 0), IceInternal::Property("IceGridAdmin.Discovery.Reply.MessageSizeMax", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.ACM.Timeout", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.ACM.Heartbeat", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.ACM.Close", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.ACM", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.AdapterId", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Endpoints", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.EndpointSelection", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.ConnectionCached", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.PreferSecure", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.InvocationTimeout", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.Locator", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.Router", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.CollocationOptimized", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.Context.*", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.PublishedEndpoints", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.ReplicaGroupId", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.EndpointSelection", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.ConnectionCached", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.PreferSecure", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.LocatorCacheTimeout", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.InvocationTimeout", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.Locator", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.Router", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.CollocationOptimized", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.Context.*", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.Router", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.ProxyOptions", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.ThreadPool.Size", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.ThreadPool.SizeMax", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.ThreadPool.SizeWarn", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.ThreadPool.StackSize", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.ThreadPool.Serialize", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.ThreadPool.ThreadIdleTime", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.ThreadPool.ThreadPriority", false, 0), + IceInternal::Property("IceGridAdmin.Discovery.Locator.MessageSizeMax", false, 0), IceInternal::Property("IceGridAdmin.Trace.Observers", false, 0), IceInternal::Property("IceGridAdmin.Trace.SaveToRegistry", false, 0), }; diff --git a/cpp/src/Ice/PropertyNames.h b/cpp/src/Ice/PropertyNames.h index 3479ab66c1e..171fa1bed8c 100644 --- a/cpp/src/Ice/PropertyNames.h +++ b/cpp/src/Ice/PropertyNames.h @@ -6,7 +6,7 @@ // ICE_LICENSE file included in this distribution. // // ********************************************************************** -// Generated by makeprops.py from file ..\config\PropertyNames.xml, Fri Feb 24 18:49:18 2017 +// Generated by makeprops.py from file ./config/PropertyNames.xml, Tue Feb 28 15:01:12 2017 // IMPORTANT: Do not edit this file -- any edits made here will be lost! diff --git a/cpp/src/Ice/UdpTransceiver.cpp b/cpp/src/Ice/UdpTransceiver.cpp index 0eeba8690e2..bcb78ed2373 100755 --- a/cpp/src/Ice/UdpTransceiver.cpp +++ b/cpp/src/Ice/UdpTransceiver.cpp @@ -774,7 +774,7 @@ IceInternal::UdpTransceiver::toDetailedString() const vector<string> intfs; if(isAddressValid(_mcastAddr)) { - intfs = getInterfacesForMulticast(_mcastInterface, _mcastAddr); + intfs = getInterfacesForMulticast(_mcastInterface, getProtocolSupport(_mcastAddr)); } else { diff --git a/cpp/src/IceDiscovery/LookupI.cpp b/cpp/src/IceDiscovery/LookupI.cpp index 0f554e397d8..76fb6525f03 100644 --- a/cpp/src/IceDiscovery/LookupI.cpp +++ b/cpp/src/IceDiscovery/LookupI.cpp @@ -56,24 +56,31 @@ AdapterRequest::response(const Ice::ObjectPrxPtr& proxy, bool isReplicaGroup) return true; } -#ifdef ICE_CPP11_MAPPING void -AdapterRequest::finished(const Ice::ObjectPrxPtr& proxy) +AdapterRequest::finished(const ObjectPrxPtr& proxy) { if(proxy || _proxies.empty()) { +#ifdef ICE_CPP11_MAPPING Request<string>::finished(proxy); +#else + RequestT<string, AMD_Locator_findAdapterByIdPtr>::finished(proxy); +#endif return; } else if(_proxies.size() == 1) { +#ifdef ICE_CPP11_MAPPING Request<string>::finished(_proxies[0]); +#else + RequestT<string, AMD_Locator_findAdapterByIdPtr>::finished(_proxies[0]); +#endif return; } EndpointSeq endpoints; - shared_ptr<ObjectPrx> prx; - for(vector<shared_ptr<ObjectPrx>>::const_iterator p = _proxies.begin(); p != _proxies.end(); ++p) + ObjectPrxPtr prx; + for(vector<ObjectPrxPtr>::const_iterator p = _proxies.begin(); p != _proxies.end(); ++p) { if(!prx) { @@ -82,37 +89,12 @@ AdapterRequest::finished(const Ice::ObjectPrxPtr& proxy) Ice::EndpointSeq endpts = (*p)->ice_getEndpoints(); copy(endpts.begin(), endpts.end(), back_inserter(endpoints)); } +#ifdef ICE_CPP11_MAPPING Request<string>::finished(prx->ice_endpoints(endpoints)); -} #else -void -AdapterRequest::finished(const Ice::ObjectPrxPtr& proxy) -{ - if(proxy || _proxies.empty()) - { - RequestT<std::string, Ice::AMD_Locator_findAdapterByIdPtr>::finished(proxy); - return; - } - else if(_proxies.size() == 1) - { - RequestT<std::string, Ice::AMD_Locator_findAdapterByIdPtr>::finished(_proxies[0]); - return; - } - - Ice::EndpointSeq endpoints; - Ice::ObjectPrxPtr prx; - for(vector<Ice::ObjectPrxPtr>::const_iterator p = _proxies.begin(); p != _proxies.end(); ++p) - { - if(!prx) - { - prx = *p; - } - Ice::EndpointSeq endpts = (*p)->ice_getEndpoints(); - copy(endpts.begin(), endpts.end(), back_inserter(endpoints)); - } - RequestT<std::string, Ice::AMD_Locator_findAdapterByIdPtr>::finished(prx->ice_endpoints(endpoints)); -} + RequestT<string, AMD_Locator_findAdapterByIdPtr>::finished(prx->ice_endpoints(endpoints)); #endif +} void AdapterRequest::runTimerTask() @@ -134,13 +116,52 @@ ObjectRequest::runTimerTask() LookupI::LookupI(const LocatorRegistryIPtr& registry, const LookupPrxPtr& lookup, const Ice::PropertiesPtr& properties) : _registry(registry), - _lookup(lookup), _timeout(IceUtil::Time::milliSeconds(properties->getPropertyAsIntWithDefault("IceDiscovery.Timeout", 300))), _retryCount(properties->getPropertyAsIntWithDefault("IceDiscovery.RetryCount", 3)), _latencyMultiplier(properties->getPropertyAsIntWithDefault("IceDiscovery.LatencyMultiplier", 1)), _domainId(properties->getProperty("IceDiscovery.DomainId")), _timer(IceInternal::getInstanceTimer(lookup->ice_getCommunicator())) { +#ifndef ICE_CPP11_MAPPING + __setNoDelete(true); +#endif + try + { + // Ensure we can establish a connection to the multicast proxy + lookup->ice_getConnection(); + } + catch(const Ice::LocalException& ex) + { + ostringstream os; + os << "IceDiscovery is unable to establish a multicast connection:\n"; + os << "proxy = " << lookup << '\n'; + os << ex; + throw Ice::PluginInitializationException(__FILE__, __LINE__, os.str()); + } + + // + // Create one lookup proxy per endpoint from the given proxy. We want to send a multicast + // datagram on each endpoint. + // + EndpointSeq endpoints = lookup->ice_getEndpoints(); + for(vector<EndpointPtr>::const_iterator p = endpoints.begin(); p != endpoints.end(); ++p) + { + try + { + EndpointSeq single; + single.push_back(*p); + LookupPrxPtr l = lookup->ice_endpoints(single); + l->ice_getConnection(); + _lookup.push_back(make_pair(l, LookupReplyPrxPtr())); + } + catch(const Ice::LocalException&) + { + } + } + assert(!_lookup.empty()); +#ifndef ICE_CPP11_MAPPING + __setNoDelete(false); +#endif } LookupI::~LookupI() @@ -168,7 +189,32 @@ LookupI::destroy() void LookupI::setLookupReply(const LookupReplyPrxPtr& lookupReply) { - _lookupReply = lookupReply; + // + // Use a lookup reply proxy whose adress matches the interface used to send multicast datagrams. + // + for(vector<pair<LookupPrxPtr, LookupReplyPrxPtr> >::iterator p = _lookup.begin(); p != _lookup.end(); ++p) + { + UDPEndpointInfoPtr info = ICE_DYNAMIC_CAST(UDPEndpointInfo, p->first->ice_getEndpoints()[0]->getInfo()); + if(info && !info->mcastInterface.empty()) + { + EndpointSeq endpts = lookupReply->ice_getEndpoints(); + for(EndpointSeq::const_iterator q = endpts.begin(); q != endpts.end(); ++q) + { + IPEndpointInfoPtr r = ICE_DYNAMIC_CAST(IPEndpointInfo, (*q)->getInfo()); + if(r && r->host == info->mcastInterface) + { + EndpointSeq single; + single.push_back(*q); + p->second = lookupReply->ice_endpoints(single); + } + } + } + + if(!p->second) + { + p->second = lookupReply; // Fallback: just use the given lookup reply proxy if no matching endpoint found. + } + } } void @@ -242,107 +288,85 @@ LookupI::findAdapterById(const string& domainId, const string& adapterId, const } } -#ifdef ICE_CPP11_MAPPING void -LookupI::findObject(function<void(const shared_ptr<Ice::ObjectPrx>&)> response, const Ice::Identity& id) -{ - Lock sync(*this); - map<Ice::Identity, ObjectRequestPtr>::iterator p = _objectRequests.find(id); - if(p == _objectRequests.end()) - { - p = _objectRequests.insert(make_pair(id, make_shared<ObjectRequest>(shared_from_this(), id, _retryCount))).first; - } - - if(p->second->addCallback(response)) - { - try - { - _lookup->findObjectByIdAsync(_domainId, id, _lookupReply); - _timer->schedule(p->second, _timeout); - } - catch(const Ice::LocalException&) - { - p->second->finished(nullptr); - _objectRequests.erase(p); - } - } -} - -void -LookupI::findAdapter(function<void(const shared_ptr<Ice::ObjectPrx>&)> response, const std::string& adapterId) -{ - Lock sync(*this); - map<string, AdapterRequestPtr>::iterator p = _adapterRequests.find(adapterId); - if(p == _adapterRequests.end()) - { - p = _adapterRequests.insert(make_pair(adapterId, make_shared<AdapterRequest>(shared_from_this(), adapterId, _retryCount))).first; - } - - if(p->second->addCallback(response)) - { - try - { - _lookup->findAdapterByIdAsync(_domainId, adapterId, _lookupReply); - _timer->schedule(p->second, _timeout); - } - catch(const Ice::LocalException&) - { - p->second->finished(0); - _adapterRequests.erase(p); - } - } -} +#ifdef ICE_CPP11_MAPPING +LookupI::findObject(function<void(const shared_ptr<Ice::ObjectPrx>&)> cb, const Ice::Identity& id) #else -void LookupI::findObject(const Ice::AMD_Locator_findObjectByIdPtr& cb, const Ice::Identity& id) +#endif { Lock sync(*this); map<Ice::Identity, ObjectRequestPtr>::iterator p = _objectRequests.find(id); if(p == _objectRequests.end()) { - p = _objectRequests.insert(make_pair(id, new ObjectRequest(this, id, _retryCount))).first; + p = _objectRequests.insert(make_pair(id, ICE_MAKE_SHARED(ObjectRequest, + ICE_SHARED_FROM_THIS, + id, + _retryCount))).first; } if(p->second->addCallback(cb)) { try { - _lookup->begin_findObjectById(_domainId, id, _lookupReply); + for(vector<pair<LookupPrxPtr, LookupReplyPrxPtr> >::const_iterator l = _lookup.begin(); l != _lookup.end(); + ++l) + { +#ifdef ICE_CPP11_MAPPING + l->first->findObjectByIdAsync(_domainId, id, l->second); +#else + l->first->begin_findObjectById(_domainId, id, l->second); +#endif + } _timer->schedule(p->second, _timeout); } catch(const Ice::LocalException&) { - p->second->finished(0); + p->second->finished(ICE_NULLPTR); _objectRequests.erase(p); } } } void +#ifdef ICE_CPP11_MAPPING +LookupI::findAdapter(function<void(const shared_ptr<Ice::ObjectPrx>&)> cb, const std::string& adapterId) +#else LookupI::findAdapter(const Ice::AMD_Locator_findAdapterByIdPtr& cb, const std::string& adapterId) +#endif { Lock sync(*this); map<string, AdapterRequestPtr>::iterator p = _adapterRequests.find(adapterId); if(p == _adapterRequests.end()) { - p = _adapterRequests.insert(make_pair(adapterId, new AdapterRequest(this, adapterId, _retryCount))).first; + p = _adapterRequests.insert(make_pair(adapterId, ICE_MAKE_SHARED(AdapterRequest, + ICE_SHARED_FROM_THIS, + adapterId, + _retryCount))).first; } if(p->second->addCallback(cb)) { try { - _lookup->begin_findAdapterById(_domainId, adapterId, _lookupReply); + for(vector<pair<LookupPrxPtr, LookupReplyPrxPtr> >::const_iterator l = _lookup.begin(); l != _lookup.end(); + ++l) + { +#ifdef ICE_CPP11_MAPPING + l->first->findAdapterByIdAsync(_domainId, adapterId, l->second); +#else + l->first->begin_findAdapterById(_domainId, adapterId, l->second); +#endif + } _timer->schedule(p->second, _timeout); } catch(const Ice::LocalException&) { - p->second->finished(0); + p->second->finished(ICE_NULLPTR); _adapterRequests.erase(p); } } } -#endif void LookupI::foundObject(const Ice::Identity& id, const Ice::ObjectPrxPtr& proxy) @@ -390,11 +414,15 @@ LookupI::objectRequestTimedOut(const ObjectRequestPtr& request) { try { + for(vector<pair<LookupPrxPtr, LookupReplyPrxPtr> >::const_iterator l = _lookup.begin(); l != _lookup.end(); + ++l) + { #ifdef ICE_CPP11_MAPPING - _lookup->findObjectByIdAsync(_domainId, request->getId(), _lookupReply); + l->first->findObjectByIdAsync(_domainId, request->getId(), l->second); #else - _lookup->begin_findObjectById(_domainId, request->getId(), _lookupReply); + l->first->begin_findObjectById(_domainId, request->getId(), l->second); #endif + } _timer->schedule(p->second, _timeout); return; } @@ -422,11 +450,15 @@ LookupI::adapterRequestTimedOut(const AdapterRequestPtr& request) { try { + for(vector<pair<LookupPrxPtr, LookupReplyPrxPtr> >::const_iterator l = _lookup.begin(); l != _lookup.end(); + ++l) + { #ifdef ICE_CPP11_MAPPING - _lookup->findAdapterByIdAsync(_domainId, request->getId(), _lookupReply); + l->first->findAdapterByIdAsync(_domainId, request->getId(), l->second); #else - _lookup->begin_findAdapterById(_domainId, request->getId(), _lookupReply); + l->first->begin_findAdapterById(_domainId, request->getId(), l->second); #endif + } _timer->schedule(p->second, _timeout); return; } diff --git a/cpp/src/IceDiscovery/LookupI.h b/cpp/src/IceDiscovery/LookupI.h index fed98927913..46f582d6118 100644 --- a/cpp/src/IceDiscovery/LookupI.h +++ b/cpp/src/IceDiscovery/LookupI.h @@ -255,8 +255,7 @@ public: private: LocatorRegistryIPtr _registry; - const LookupPrxPtr _lookup; - LookupReplyPrxPtr _lookupReply; + std::vector<std::pair<LookupPrxPtr, LookupReplyPrxPtr> > _lookup; const IceUtil::Time _timeout; const int _retryCount; const int _latencyMultiplier; diff --git a/cpp/src/IceDiscovery/PluginI.cpp b/cpp/src/IceDiscovery/PluginI.cpp index 2275459c04f..fa6e65bc5b2 100644 --- a/cpp/src/IceDiscovery/PluginI.cpp +++ b/cpp/src/IceDiscovery/PluginI.cpp @@ -9,6 +9,7 @@ #include <IceUtil/IceUtil.h> #include <Ice/Ice.h> +#include <Ice/Network.h> // For getInterfacesForMulticast #include <IceDiscovery/PluginI.h> #include <IceDiscovery/LocatorI.h> @@ -87,16 +88,33 @@ PluginI::initialize() } properties->setProperty("IceDiscovery.Multicast.Endpoints", os.str()); } - if(properties->getProperty("IceDiscovery.Reply.Endpoints").empty()) + + string lookupEndpoints = properties->getProperty("IceDiscovery.Lookup"); + if(lookupEndpoints.empty()) { - ostringstream os; - os << "udp"; - if(!intf.empty()) + // + // If no lookup endpoints are specified, we get all the network interfaces and create + // an endpoint for each of them. We'll send UDP multicast packages on each interface. + // + IceInternal::ProtocolSupport protocol = ipv4 && !preferIPv6 ? IceInternal::EnableIPv4 : IceInternal::EnableIPv6; + vector<string> interfaces = IceInternal::getInterfacesForMulticast(intf, protocol); + ostringstream lookup; + for(vector<string>::const_iterator p = interfaces.begin(); p != interfaces.end(); ++p) { - os << " -h \"" << intf << "\""; + if(p != interfaces.begin()) + { + lookup << ":"; + } + lookup << "udp -h \"" << address << "\" -p " << port << " --interface \"" << *p << "\""; } - properties->setProperty("IceDiscovery.Reply.Endpoints", os.str()); + lookupEndpoints = lookup.str(); } + + if(properties->getProperty("IceDiscovery.Reply.Endpoints").empty()) + { + properties->setProperty("IceDiscovery.Reply.Endpoints", "udp -h " + (intf.empty() ? "*" : "\"" + intf + "\"")); + } + if(properties->getProperty("IceDiscovery.Locator.Endpoints").empty()) { properties->setProperty("IceDiscovery.Locator.AdapterId", Ice::generateUUID()); @@ -113,42 +131,8 @@ PluginI::initialize() Ice::LocatorRegistryPrxPtr locatorRegistryPrx = ICE_UNCHECKED_CAST(Ice::LocatorRegistryPrx, _locatorAdapter->addWithUUID(locatorRegistry)); - string lookupEndpoints = properties->getProperty("IceDiscovery.Lookup"); - if(lookupEndpoints.empty()) - { - ostringstream os; - os << "udp -h \"" << address << "\" -p " << port; - if(!intf.empty()) - { - os << " --interface \"" << intf << "\""; - } - lookupEndpoints = os.str(); - } - Ice::ObjectPrxPtr lookupPrx = _communicator->stringToProxy("IceDiscovery/Lookup -d:" + lookupEndpoints); lookupPrx = lookupPrx->ice_collocationOptimized(false); // No collocation optimization for the multicast proxy! - try - { - // Ensure we can establish a connection to the multicast proxy - // but don't block. -#ifdef ICE_CPP11_MAPPING - lookupPrx->ice_getConnection(); -#else - Ice::AsyncResultPtr result = lookupPrx->begin_ice_getConnection(); - if(result->sentSynchronously()) - { - lookupPrx->end_ice_getConnection(result); - } -#endif - } - catch(const Ice::LocalException& ex) - { - ostringstream os; - os << "IceDiscovery is unable to establish a multicast connection:\n"; - os << "proxy = " << lookupPrx << '\n'; - os << ex; - throw Ice::PluginInitializationException(__FILE__, __LINE__, os.str()); - } // // Add lookup and lookup reply Ice objects diff --git a/cpp/src/IceGrid/Client.cpp b/cpp/src/IceGrid/Client.cpp index 35721f3cf74..3473bdb72ca 100644 --- a/cpp/src/IceGrid/Client.cpp +++ b/cpp/src/IceGrid/Client.cpp @@ -21,7 +21,7 @@ #include <IceGrid/Parser.h> #include <IceGrid/FileParserI.h> #include <IceGrid/Registry.h> -#include <IceGrid/IceLocatorDiscovery.h> +#include <IceLocatorDiscovery/Plugin.h> #include <Glacier2/Router.h> #include <fstream> @@ -68,74 +68,6 @@ public: Init init; -class LookupReplyI : public LookupReply, private IceUtil::Monitor<IceUtil::Mutex> -{ -public: - - virtual void - foundLocator(const Ice::LocatorPrx& locator, const Ice::Current&) - { - Lock sync(*this); - for(vector<Ice::LocatorPrx>::iterator p = _locators.begin(); p != _locators.end(); ++p) - { - if((*p)->ice_getIdentity() == locator->ice_getIdentity()) - { - Ice::EndpointSeq newEndpoints = (*p)->ice_getEndpoints(); - Ice::EndpointSeq endpts = locator->ice_getEndpoints(); - for(Ice::EndpointSeq::const_iterator r = endpts.begin(); r != endpts.end(); ++r) - { - // - // Only add unknown endpoints - // - bool found = false; - for(Ice::EndpointSeq::const_iterator q = newEndpoints.begin(); q != newEndpoints.end(); ++q) - { - if(*r == *q) - { - found = true; - break; - } - } - if(!found) - { - newEndpoints.push_back(*r); - } - } - *p = (*p)->ice_endpoints(newEndpoints); - return; - } - } - _locators.push_back(locator); - notify(); - } - - vector<Ice::LocatorPrx> - getLocators() - { - Lock sync(*this); - return _locators; - } - - bool - waitForLocator() - { - Lock sync(*this); - while(_locators.empty()) - { - if(!timedWait(IceUtil::Time::milliSeconds(300))) - { - return false; - } - } - return true; - } - -private: - - vector<Ice::LocatorPrx> _locators; -}; -typedef IceUtil::Handle<LookupReplyI> LookupReplyIPtr; - } class SessionKeepAliveThread : public IceUtil::Thread, public IceUtil::Monitor<IceUtil::Mutex> @@ -297,6 +229,8 @@ Client::usage() ; } +extern "C" ICE_LOCATOR_DISCOVERY_API Ice::Plugin* +createIceLocatorDiscovery(const Ice::CommunicatorPtr&, const string&, const Ice::StringSeq&); int Client::main(StringSeq& args) @@ -539,74 +473,17 @@ Client::run(StringSeq& originalArgs) } else { - bool ipv4 = properties->getPropertyAsIntWithDefault("Ice.IPv4", 1) > 0; - string address; - bool preferIPv6 = properties->getPropertyAsInt("Ice.PreferIPv6Address") > 0; - if(ipv4 && !preferIPv6) - { - address = properties->getPropertyWithDefault("IceGridAdmin.Discovery.Address", "239.255.0.1"); - } - else - { - address = properties->getPropertyWithDefault("IceGridAdmin.Discovery.Address", "ff15::1"); - } - - string interface = properties->getProperty("IceGridAdmin.Discovery.Interface"); - - string lookupEndpoints = properties->getProperty("IceGridAdmin.Discovery.Lookup"); - if(lookupEndpoints.empty()) - { - ostringstream os; - os << "udp -h \"" << address << "\" -p " << (port == 0 ? 4061 : port); - if(!interface.empty()) - { - os << " --interface \"" << interface << "\""; - } - lookupEndpoints = os.str(); - } - - ObjectPrx prx = communicator()->stringToProxy("IceLocatorDiscovery/Lookup -d:" + lookupEndpoints); - LookupPrx lookupPrx = LookupPrx::uncheckedCast(prx->ice_collocationOptimized(false)); - - if(properties->getProperty("IceGridAdmin.Discovery.Reply.Endpoints").empty()) - { - ostringstream os; - os << "udp"; - if(!interface.empty()) - { - os << " -h \"" << interface << "\""; - } - properties->setProperty("IceGridAdmin.Discovery.Reply.Endpoints", os.str()); - } - - Ice::ObjectAdapterPtr adapter = communicator()->createObjectAdapter("IceGridAdmin.Discovery.Reply"); - adapter->activate(); - LookupReplyIPtr reply = new LookupReplyI(); - LookupReplyPrx replyPrx = LookupReplyPrx::uncheckedCast(adapter->addWithUUID(reply)->ice_datagram()); - int retryCount = 3; // Send several findLocator queries. - try - { - while(--retryCount >= 0) - { - lookupPrx->findLocator(instanceName, replyPrx); - if(instanceName.empty()) - { - IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(300)); - } - else if(reply->waitForLocator()) - { - break; - } - } - } - catch(const Ice::LocalException& ex) - { - consoleErr << _appName << ": registry discovery failed:\n" << ex << endl; - return EXIT_FAILURE; - } - adapter->destroy(); + // + // NOTE: we don't configure the plugin with the Ice communicator on initialization + // because it would install a default locator. Instead, we create the plugin here + // to lookup for locator proxies. We destroy the plugin, once we have selected a + // locator. + // + Ice::PluginPtr p = createIceLocatorDiscovery(communicator(), "IceGridAdmin.Discovery", Ice::StringSeq()); + IceLocatorDiscovery::PluginPtr plugin = IceLocatorDiscovery::PluginPtr::dynamicCast(p); + plugin->initialize(); - vector<Ice::LocatorPrx> locators = reply->getLocators(); + vector<Ice::LocatorPrx> locators = plugin->getLocators(instanceName, IceUtil::Time::milliSeconds(300)); if(locators.size() > 1) { consoleOut << "found " << locators.size() << " Ice locators:" << endl; @@ -644,6 +521,15 @@ Client::run(StringSeq& originalArgs) consoleOut << "using discovered locator:\nproxy = `" << locators[0] << "'" << endl; communicator()->setDefaultLocator(locators[0]); } + else + { + communicator()->setDefaultLocator(0); + } + + // + // Destroy the plugin, we no longer need it. + // + plugin->destroy(); } } diff --git a/cpp/src/IceGrid/Makefile.mk b/cpp/src/IceGrid/Makefile.mk index 4e14f08b10b..c3ab9e190a2 100644 --- a/cpp/src/IceGrid/Makefile.mk +++ b/cpp/src/IceGrid/Makefile.mk @@ -78,9 +78,8 @@ icegridregistry_sources := $(addprefix $(currentdir)/,$(local_registry_srcs) I icegridregistry_dependencies := IceBox IceStormService IceStorm IceXML IceSSL IcePatch2 IceDB $(local_dependencies) icegridregistry_cppflags := $(if $(lmdb_includedir),-I$(lmdb_includedir)) -icegridadmin_dependencies := IcePatch2 IceBox IceXML -icegridadmin_sources := $(slicedir)/IceLocatorDiscovery/IceLocatorDiscovery.ice \ - $(addprefix $(currentdir)/,$(local_admin_srcs)) +icegridadmin_dependencies := IcePatch2 IceBox IceXML IceLocatorDiscovery +icegridadmin_sources := $(addprefix $(currentdir)/,$(local_admin_srcs)) projects += $(project) diff --git a/cpp/src/IceGrid/msbuild/icegridadmin/icegridadmin.vcxproj b/cpp/src/IceGrid/msbuild/icegridadmin/icegridadmin.vcxproj index bbc62f79b1c..65ef495834a 100644 --- a/cpp/src/IceGrid/msbuild/icegridadmin/icegridadmin.vcxproj +++ b/cpp/src/IceGrid/msbuild/icegridadmin/icegridadmin.vcxproj @@ -105,41 +105,21 @@ <ClCompile Include="..\..\Parser.cpp" /> <ClCompile Include="..\..\Scanner.cpp" /> <ClCompile Include="..\..\Util.cpp" /> - <ClCompile Include="Win32\Debug\IceLocatorDiscovery.cpp"> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> - </ClCompile> <ClCompile Include="Win32\Debug\Internal.cpp"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="Win32\Release\IceLocatorDiscovery.cpp"> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> - </ClCompile> <ClCompile Include="Win32\Release\Internal.cpp"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="x64\Debug\IceLocatorDiscovery.cpp"> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> - </ClCompile> <ClCompile Include="x64\Debug\Internal.cpp"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="x64\Release\IceLocatorDiscovery.cpp"> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> - </ClCompile> <ClCompile Include="x64\Release\Internal.cpp"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> @@ -147,45 +127,24 @@ </ClCompile> </ItemGroup> <ItemGroup> - <IceBuilder Include="..\..\..\..\..\slice\IceLocatorDiscovery\IceLocatorDiscovery.ice" /> <IceBuilder Include="..\..\Internal.ice" /> </ItemGroup> <ItemGroup> - <ClInclude Include="Win32\Debug\IceGrid\IceLocatorDiscovery.h"> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> - </ClInclude> <ClInclude Include="Win32\Debug\IceGrid\Internal.h"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> </ClInclude> - <ClInclude Include="Win32\Release\IceGrid\IceLocatorDiscovery.h"> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> - </ClInclude> <ClInclude Include="Win32\Release\IceGrid\Internal.h"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> </ClInclude> - <ClInclude Include="x64\Debug\IceGrid\IceLocatorDiscovery.h"> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> - </ClInclude> <ClInclude Include="x64\Debug\IceGrid\Internal.h"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> </ClInclude> - <ClInclude Include="x64\Release\IceGrid\IceLocatorDiscovery.h"> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> - </ClInclude> <ClInclude Include="x64\Release\IceGrid\Internal.h"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> diff --git a/cpp/src/IceGrid/msbuild/icegridadmin/icegridadmin.vcxproj.filters b/cpp/src/IceGrid/msbuild/icegridadmin/icegridadmin.vcxproj.filters index fc0cc2249bc..d63f7b210fc 100644 --- a/cpp/src/IceGrid/msbuild/icegridadmin/icegridadmin.vcxproj.filters +++ b/cpp/src/IceGrid/msbuild/icegridadmin/icegridadmin.vcxproj.filters @@ -82,61 +82,34 @@ <ClCompile Include="..\..\Util.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="Win32\Debug\IceLocatorDiscovery.cpp"> - <Filter>Source Files\Win32\Debug</Filter> - </ClCompile> <ClCompile Include="Win32\Debug\Internal.cpp"> <Filter>Source Files\Win32\Debug</Filter> </ClCompile> - <ClCompile Include="x64\Debug\IceLocatorDiscovery.cpp"> - <Filter>Source Files\x64\Debug</Filter> - </ClCompile> <ClCompile Include="x64\Debug\Internal.cpp"> <Filter>Source Files\x64\Debug</Filter> </ClCompile> - <ClCompile Include="Win32\Release\IceLocatorDiscovery.cpp"> - <Filter>Source Files\Win32\Release</Filter> - </ClCompile> <ClCompile Include="Win32\Release\Internal.cpp"> <Filter>Source Files\Win32\Release</Filter> </ClCompile> - <ClCompile Include="x64\Release\IceLocatorDiscovery.cpp"> - <Filter>Source Files\x64\Release</Filter> - </ClCompile> <ClCompile Include="x64\Release\Internal.cpp"> <Filter>Source Files\x64\Release</Filter> </ClCompile> </ItemGroup> <ItemGroup> - <IceBuilder Include="..\..\..\..\..\slice\IceLocatorDiscovery\IceLocatorDiscovery.ice"> - <Filter>Slice Files</Filter> - </IceBuilder> <IceBuilder Include="..\..\Internal.ice"> <Filter>Slice Files</Filter> </IceBuilder> </ItemGroup> <ItemGroup> - <ClInclude Include="Win32\Debug\IceGrid\IceLocatorDiscovery.h"> - <Filter>Header Files\Win32\Debug</Filter> - </ClInclude> <ClInclude Include="Win32\Debug\IceGrid\Internal.h"> <Filter>Header Files\Win32\Debug</Filter> </ClInclude> - <ClInclude Include="x64\Debug\IceGrid\IceLocatorDiscovery.h"> - <Filter>Header Files\x64\Debug</Filter> - </ClInclude> <ClInclude Include="x64\Debug\IceGrid\Internal.h"> <Filter>Header Files\x64\Debug</Filter> </ClInclude> - <ClInclude Include="Win32\Release\IceGrid\IceLocatorDiscovery.h"> - <Filter>Header Files\Win32\Release</Filter> - </ClInclude> <ClInclude Include="Win32\Release\IceGrid\Internal.h"> <Filter>Header Files\Win32\Release</Filter> </ClInclude> - <ClInclude Include="x64\Release\IceGrid\IceLocatorDiscovery.h"> - <Filter>Header Files\x64\Release</Filter> - </ClInclude> <ClInclude Include="x64\Release\IceGrid\Internal.h"> <Filter>Header Files\x64\Release</Filter> </ClInclude> diff --git a/cpp/src/IceLocatorDiscovery/Plugin.h b/cpp/src/IceLocatorDiscovery/Plugin.h new file mode 100644 index 00000000000..f9e02b1166a --- /dev/null +++ b/cpp/src/IceLocatorDiscovery/Plugin.h @@ -0,0 +1,52 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef LOCATOR_DISCOVERY_PLUGIN_I_H +#define LOCATOR_DISCOVERY_PLUGIN_I_H + +#include <Ice/Config.h> +#include <Ice/Plugin.h> +#include <Ice/Locator.h> +#include <IceUtil/Time.h> + +// +// Automatically link IceLocatorDiscovery[D|++11|++11D].lib with Visual C++ +// +#if !defined(ICE_BUILDING_ICE_LOCATOR_DISCOVERY) && defined(ICE_LOCATOR_DISCOVERY_API_EXPORTS) +# define ICE_BUILDING_ICE_LOCATOR_DISCOVERY +#endif + +#if defined(_MSC_VER) && !defined(ICE_BUILDING_ICE_LOCATOR_DISCOVERY) +# pragma comment(lib, ICE_LIBNAME("IceLocatorDiscovery")) +#endif + +#ifndef ICE_LOCATOR_DISCOVERY_API +# if defined(ICE_STATIC_LIBS) +# define ICE_LOCATOR_DISCOVERY_API /**/ +# elif defined(ICE_LOCATOR_DISCOVERY_API_EXPORTS) +# define ICE_LOCATOR_DISCOVERY_API ICE_DECLSPEC_EXPORT +# else +# define ICE_LOCATOR_DISCOVERY_API ICE_DECLSPEC_IMPORT +# endif +#endif + +namespace IceLocatorDiscovery +{ + +class ICE_LOCATOR_DISCOVERY_API Plugin : public Ice::Plugin +{ +public: + + virtual std::vector<Ice::LocatorPrxPtr> getLocators(const std::string&, const IceUtil::Time&) const = 0; +}; +ICE_DEFINE_PTR(PluginPtr, Plugin); + +}; + +#endif diff --git a/cpp/src/IceLocatorDiscovery/PluginI.cpp b/cpp/src/IceLocatorDiscovery/PluginI.cpp index d68d4eacf34..7948fa13870 100644 --- a/cpp/src/IceLocatorDiscovery/PluginI.cpp +++ b/cpp/src/IceLocatorDiscovery/PluginI.cpp @@ -9,50 +9,14 @@ #include <IceUtil/IceUtil.h> #include <Ice/Ice.h> +#include <Ice/Network.h> // For getInterfacesForMulticast -#include <IceLocatorDiscovery/PluginI.h> +#include <IceLocatorDiscovery/Plugin.h> #include <IceLocatorDiscovery/IceLocatorDiscovery.h> using namespace std; using namespace IceLocatorDiscovery; -#ifndef ICE_LOCATOR_DISCOVERY_API -# ifdef ICE_LOCATOR_DISCOVERY_API_EXPORTS -# define ICE_LOCATOR_DISCOVERY_API ICE_DECLSPEC_EXPORT -# else -# define ICE_LOCATOR_DISCOVERY_API /**/ -# endif -#endif - -// -// Plugin factory function. -// -extern "C" ICE_LOCATOR_DISCOVERY_API Ice::Plugin* -createIceLocatorDiscovery(const Ice::CommunicatorPtr& communicator, const string&, const Ice::StringSeq&) -{ - return new PluginI(communicator); -} - -namespace Ice -{ - -ICE_LOCATOR_DISCOVERY_API void -registerIceLocatorDiscovery(bool loadOnInitialize) -{ - Ice::registerPluginFactory("IceLocatorDiscovery", createIceLocatorDiscovery, loadOnInitialize); -} - -} - -// -// Objective-C function to allow Objective-C programs to register plugin. -// -extern "C" ICE_LOCATOR_DISCOVERY_API void -ICEregisterIceLocatorDiscovery(bool loadOnInitialize) -{ - Ice::registerIceLocatorDiscovery(loadOnInitialize); -} - namespace { @@ -136,7 +100,7 @@ class LocatorI : public Ice::BlobjectArrayAsync, { public: - LocatorI(const LookupPrxPtr&, const Ice::PropertiesPtr&, const string&, const Ice::LocatorPrxPtr&); + LocatorI(const string&, const LookupPrxPtr&, const Ice::PropertiesPtr&, const string&, const Ice::LocatorPrxPtr&); void setLookupReply(const LookupReplyPrxPtr&); #ifdef ICE_CPP11_MAPPING @@ -152,11 +116,13 @@ public: void foundLocator(const Ice::LocatorPrxPtr&); void invoke(const Ice::LocatorPrxPtr&, const RequestPtr&); + vector<Ice::LocatorPrxPtr> getLocators(const string&, const IceUtil::Time&); + private: virtual void runTimerTask(); - const LookupPrxPtr _lookup; + vector<pair<LookupPrxPtr, LookupReplyPrxPtr> > _lookup; const IceUtil::Time _timeout; const int _retryCount; const IceUtil::Time _retryDelay; @@ -164,8 +130,8 @@ private: string _instanceName; bool _warned; - LookupReplyPrxPtr _lookupReply; Ice::LocatorPrxPtr _locator; + map<string, Ice::LocatorPrxPtr> _locators; Ice::LocatorPrxPtr _voidLocator; IceUtil::Time _nextRetry; @@ -246,9 +212,58 @@ public: } }; +class PluginI : public Plugin +{ +public: + + PluginI(const std::string&, const Ice::CommunicatorPtr&); + + virtual void initialize(); + virtual void destroy(); + virtual vector<Ice::LocatorPrxPtr> getLocators(const string&, const IceUtil::Time&) const; + +private: + + const string _name; + const Ice::CommunicatorPtr _communicator; + Ice::ObjectAdapterPtr _locatorAdapter; + Ice::ObjectAdapterPtr _replyAdapter; + LocatorIPtr _locator; +}; + +} + +// +// Plugin factory function. +// +extern "C" ICE_LOCATOR_DISCOVERY_API Ice::Plugin* +createIceLocatorDiscovery(const Ice::CommunicatorPtr& communicator, const string& name, const Ice::StringSeq&) +{ + return new PluginI(name, communicator); +} + +namespace Ice +{ + +ICE_LOCATOR_DISCOVERY_API void +registerIceLocatorDiscovery(bool loadOnInitialize) +{ + Ice::registerPluginFactory("IceLocatorDiscovery", createIceLocatorDiscovery, loadOnInitialize); +} + } -PluginI::PluginI(const Ice::CommunicatorPtr& communicator) : _communicator(communicator) +// +// Objective-C function to allow Objective-C programs to register plugin. +// +extern "C" ICE_LOCATOR_DISCOVERY_API void +ICEregisterIceLocatorDiscovery(bool loadOnInitialize) +{ + Ice::registerIceLocatorDiscovery(loadOnInitialize); +} + +PluginI::PluginI(const string& name, const Ice::CommunicatorPtr& communicator) : + _name(name), _communicator(communicator) { } @@ -262,109 +277,80 @@ PluginI::initialize() string address; if(ipv4 && !preferIPv6) { - address = properties->getPropertyWithDefault("IceLocatorDiscovery.Address", "239.255.0.1"); + address = properties->getPropertyWithDefault(_name + ".Address", "239.255.0.1"); } else { - address = properties->getPropertyWithDefault("IceLocatorDiscovery.Address", "ff15::1"); + address = properties->getPropertyWithDefault(_name + ".Address", "ff15::1"); } - int port = properties->getPropertyAsIntWithDefault("IceLocatorDiscovery.Port", 4061); - string intf = properties->getProperty("IceLocatorDiscovery.Interface"); + int port = properties->getPropertyAsIntWithDefault(_name + ".Port", 4061); + string intf = properties->getProperty(_name + ".Interface"); - if(properties->getProperty("IceLocatorDiscovery.Reply.Endpoints").empty()) + string lookupEndpoints = properties->getProperty(_name + ".Lookup"); + if(lookupEndpoints.empty()) { - ostringstream os; - os << "udp"; - if(!intf.empty()) + // + // If no lookup endpoints are specified, we get all the network interfaces and create + // an endpoint for each of them. We'll send UDP multicast packages on each interface. + // + IceInternal::ProtocolSupport protocol = ipv4 && !preferIPv6 ? IceInternal::EnableIPv4 : IceInternal::EnableIPv6; + vector<string> interfaces = IceInternal::getInterfacesForMulticast(intf, protocol); + ostringstream lookup; + for(vector<string>::const_iterator p = interfaces.begin(); p != interfaces.end(); ++p) { - os << " -h \"" << intf << "\""; + if(p != interfaces.begin()) + { + lookup << ":"; + } + lookup << "udp -h \"" << address << "\" -p " << port << " --interface \"" << *p << "\""; } - properties->setProperty("IceLocatorDiscovery.Reply.Endpoints", os.str()); + lookupEndpoints = lookup.str(); + } + + if(properties->getProperty(_name + ".Reply.Endpoints").empty()) + { + properties->setProperty(_name + ".Reply.Endpoints", "udp -h " + (intf.empty() ? "*" : "\"" + intf + "\"")); } - if(properties->getProperty("IceLocatorDiscovery.Locator.Endpoints").empty()) + + if(properties->getProperty(_name + ".Locator.Endpoints").empty()) { - properties->setProperty("IceLocatorDiscovery.Locator.AdapterId", Ice::generateUUID()); // Collocated adapter + properties->setProperty(_name + ".Locator.AdapterId", Ice::generateUUID()); // Collocated adapter } - _replyAdapter = _communicator->createObjectAdapter("IceLocatorDiscovery.Reply"); - _locatorAdapter = _communicator->createObjectAdapter("IceLocatorDiscovery.Locator"); + _replyAdapter = _communicator->createObjectAdapter(_name + ".Reply"); + _locatorAdapter = _communicator->createObjectAdapter(_name + ".Locator"); // We don't want those adapters to be registered with the locator so clear their locator. _replyAdapter->setLocator(0); _locatorAdapter->setLocator(0); - string lookupEndpoints = properties->getProperty("IceLocatorDiscovery.Lookup"); - if(lookupEndpoints.empty()) - { - ostringstream os; - os << "udp -h \"" << address << "\" -p " << port; - if(!intf.empty()) - { - os << " --interface \"" << intf << "\""; - } - lookupEndpoints = os.str(); - } - Ice::ObjectPrxPtr lookupPrx = _communicator->stringToProxy("IceLocatorDiscovery/Lookup -d:" + lookupEndpoints); lookupPrx = lookupPrx->ice_collocationOptimized(false); // No collocation optimization for the multicast proxy! - try - { - // Ensure we can establish a connection to the multicast proxy - // but don't block. -#ifdef ICE_CPP11_MAPPING - promise<bool> sent; - promise<void> completed; - - lookupPrx->ice_getConnectionAsync( - [&](shared_ptr<Ice::Connection>) - { - completed.set_value(); - }, - [&](exception_ptr ex) - { - completed.set_exception(ex); - }, - [&](bool sentSynchronously) - { - sent.set_value(sentSynchronously); - }); - if(sent.get_future().get()) - { - completed.get_future().get(); - } -#else - Ice::AsyncResultPtr result = lookupPrx->begin_ice_getConnection(); - if(result->sentSynchronously()) - { - lookupPrx->end_ice_getConnection(result); - } -#endif - } - catch(const Ice::LocalException& ex) - { - ostringstream os; - os << "IceLocatorDiscovery is unable to establish a multicast connection:\n"; - os << "proxy = " << lookupPrx << '\n'; - os << ex; - throw Ice::PluginInitializationException(__FILE__, __LINE__, os.str()); - } - Ice::LocatorPrxPtr voidLocator = ICE_UNCHECKED_CAST(Ice::LocatorPrx, _locatorAdapter->addWithUUID(ICE_MAKE_SHARED(VoidLocatorI))); + Ice::LocatorPrxPtr voidLocator = ICE_UNCHECKED_CAST(Ice::LocatorPrx, + _locatorAdapter->addWithUUID(ICE_MAKE_SHARED(VoidLocatorI))); - string instanceName = properties->getProperty("IceLocatorDiscovery.InstanceName"); + string instanceName = properties->getProperty(_name + ".InstanceName"); Ice::Identity id; id.name = "Locator"; id.category = !instanceName.empty() ? instanceName : Ice::generateUUID(); - LocatorIPtr locator = ICE_MAKE_SHARED(LocatorI, ICE_UNCHECKED_CAST(LookupPrx, lookupPrx), properties, instanceName, voidLocator); - _communicator->setDefaultLocator(ICE_UNCHECKED_CAST(Ice::LocatorPrx, _locatorAdapter->add(locator, id))); + _locator = ICE_MAKE_SHARED(LocatorI, _name, ICE_UNCHECKED_CAST(LookupPrx, lookupPrx), properties, instanceName, + voidLocator); + _communicator->setDefaultLocator(ICE_UNCHECKED_CAST(Ice::LocatorPrx, _locatorAdapter->add(_locator, id))); - Ice::ObjectPrxPtr lookupReply = _replyAdapter->addWithUUID(ICE_MAKE_SHARED(LookupReplyI, locator))->ice_datagram(); - locator->setLookupReply(ICE_UNCHECKED_CAST(LookupReplyPrx, lookupReply)); + Ice::ObjectPrxPtr lookupReply = _replyAdapter->addWithUUID(ICE_MAKE_SHARED(LookupReplyI, _locator))->ice_datagram(); + _locator->setLookupReply(ICE_UNCHECKED_CAST(LookupReplyPrx, lookupReply)); _replyAdapter->activate(); _locatorAdapter->activate(); } +vector<Ice::LocatorPrxPtr> +PluginI::getLocators(const string& instanceName, const IceUtil::Time& waitTime) const +{ + return _locator->getLocators(instanceName, waitTime); +} + void PluginI::destroy() { @@ -545,14 +531,14 @@ Request::exception(const Ice::Exception& ex) #endif } -LocatorI::LocatorI(const LookupPrxPtr& lookup, +LocatorI::LocatorI(const string& name, + const LookupPrxPtr& lookup, const Ice::PropertiesPtr& p, const string& instanceName, const Ice::LocatorPrxPtr& voidLocator) : - _lookup(lookup), - _timeout(IceUtil::Time::milliSeconds(p->getPropertyAsIntWithDefault("IceLocatorDiscovery.Timeout", 300))), - _retryCount(p->getPropertyAsIntWithDefault("IceLocatorDiscovery.RetryCount", 3)), - _retryDelay(IceUtil::Time::milliSeconds(p->getPropertyAsIntWithDefault("IceLocatorDiscovery.RetryDelay", 2000))), + _timeout(IceUtil::Time::milliSeconds(p->getPropertyAsIntWithDefault(name + ".Timeout", 300))), + _retryCount(p->getPropertyAsIntWithDefault(name + ".RetryCount", 3)), + _retryDelay(IceUtil::Time::milliSeconds(p->getPropertyAsIntWithDefault(name + ".RetryDelay", 2000))), _timer(IceInternal::getInstanceTimer(lookup->ice_getCommunicator())), _instanceName(instanceName), _warned(false), @@ -560,12 +546,77 @@ LocatorI::LocatorI(const LookupPrxPtr& lookup, _voidLocator(voidLocator), _pendingRetryCount(0) { +#ifndef ICE_CPP11_MAPPING + __setNoDelete(true); +#endif + try + { + // Ensure we can establish a connection to the multicast proxy + lookup->ice_getConnection(); + } + catch(const Ice::LocalException& ex) + { + ostringstream os; + os << "IceLocatorDiscovery is unable to establish a multicast connection:\n"; + os << "proxy = " << lookup << '\n'; + os << ex; + throw Ice::PluginInitializationException(__FILE__, __LINE__, os.str()); + } + + // + // Create one lookup proxy per endpoint from the given proxy. We want to send a multicast + // datagram on each endpoint. + // + Ice::EndpointSeq endpoints = lookup->ice_getEndpoints(); + for(vector<Ice::EndpointPtr>::const_iterator p = endpoints.begin(); p != endpoints.end(); ++p) + { + try + { + Ice::EndpointSeq single; + single.push_back(*p); + LookupPrxPtr l = lookup->ice_endpoints(single); + l->ice_getConnection(); + _lookup.push_back(make_pair(l, LookupReplyPrxPtr())); + } + catch(const Ice::LocalException&) + { + } + } + assert(!_lookup.empty()); +#ifndef ICE_CPP11_MAPPING + __setNoDelete(false); +#endif } void LocatorI::setLookupReply(const LookupReplyPrxPtr& lookupReply) { - _lookupReply = lookupReply; + // + // Use a lookup reply proxy whose adress matches the interface used to send multicast datagrams. + // + for(vector<pair<LookupPrxPtr, LookupReplyPrxPtr> >::iterator p = _lookup.begin(); p != _lookup.end(); ++p) + { + Ice::UDPEndpointInfoPtr info = ICE_DYNAMIC_CAST(Ice::UDPEndpointInfo, p->first->ice_getEndpoints()[0]->getInfo()); + if(info && !info->mcastInterface.empty()) + { + Ice::EndpointSeq endpts = lookupReply->ice_getEndpoints(); + for(Ice::EndpointSeq::const_iterator q = endpts.begin(); q != endpts.end(); ++q) + { + Ice::IPEndpointInfoPtr r = ICE_DYNAMIC_CAST(Ice::IPEndpointInfo, (*q)->getInfo()); + if(r && r->host == info->mcastInterface) + { + Ice::EndpointSeq single; + single.push_back(*q); + p->second = lookupReply->ice_endpoints(single); + } + } + } + + if(!p->second) + { + p->second = lookupReply; // Fallback: just use the given lookup reply proxy if no matching endpoint found. + } + } } #ifdef ICE_CPP11_MAPPING @@ -588,6 +639,50 @@ LocatorI::ice_invoke_async(const Ice::AMD_Object_ice_invokePtr& amdCB, } #endif +vector<Ice::LocatorPrxPtr> +LocatorI::getLocators(const string& instanceName, const IceUtil::Time& waitTime) +{ + // + // Clear locators from previous search + // + { + Lock sync(*this); + _locators.clear(); + } + + // + // Find a locator + // + invoke(ICE_NULLPTR, ICE_NULLPTR); + + // + // Wait for responses + // + if(instanceName.empty()) + { + IceUtil::ThreadControl::sleep(waitTime); + } + else + { + Lock sync(*this); + while(_locators.find(instanceName) == _locators.end() && _pendingRetryCount > 0) + { + timedWait(waitTime); + } + } + + // + // Return found locators + // + Lock sync(*this); + vector<Ice::LocatorPrxPtr> locators; + for(map<string, Ice::LocatorPrxPtr>::const_iterator p = _locators.begin(); p != _locators.end(); ++p) + { + locators.push_back(p->second); + } + return locators; +} + void LocatorI::foundLocator(const Ice::LocatorPrxPtr& locator) { @@ -601,7 +696,8 @@ LocatorI::foundLocator(const Ice::LocatorPrxPtr& locator) // If we already have a locator assigned, ensure the given locator // has the same identity, otherwise ignore it. // - if(_locator && locator->ice_getIdentity().category != _locator->ice_getIdentity().category) + if(!_pendingRequests.empty() && + _locator && locator->ice_getIdentity().category != _locator->ice_getIdentity().category) { if(!_warned) { @@ -624,13 +720,14 @@ LocatorI::foundLocator(const Ice::LocatorPrxPtr& locator) _pendingRetryCount = 0; } - if(_locator) + Ice::LocatorPrxPtr l = _pendingRequests.empty() ? _locators[locator->ice_getIdentity().category] : _locator; + if(l) { // // We found another locator replica, append its endpoints to the // current locator proxy endpoints. // - Ice::EndpointSeq newEndpoints = _locator->ice_getEndpoints(); + Ice::EndpointSeq newEndpoints = l->ice_getEndpoints(); Ice::EndpointSeq endpts = locator->ice_getEndpoints(); for(Ice::EndpointSeq::const_iterator p = endpts.begin(); p != endpts.end(); ++p) { @@ -651,25 +748,35 @@ LocatorI::foundLocator(const Ice::LocatorPrxPtr& locator) newEndpoints.push_back(*p); } } - _locator = _locator->ice_endpoints(newEndpoints); + l = l->ice_endpoints(newEndpoints); + } + else + { + l = locator; + } + + if(_pendingRequests.empty()) + { + _locators[locator->ice_getIdentity().category] = l; + notify(); } else { - _locator = locator; + _locator = l; if(_instanceName.empty()) { _instanceName = _locator->ice_getIdentity().category; // Stick to the first discovered locator. } - } - // - // Send pending requests if any. - // - for(vector<RequestPtr>::const_iterator p = _pendingRequests.begin(); p != _pendingRequests.end(); ++p) - { - (*p)->invoke(_locator); + // + // Send pending requests if any. + // + for(vector<RequestPtr>::const_iterator p = _pendingRequests.begin(); p != _pendingRequests.end(); ++p) + { + (*p)->invoke(_locator); + } + _pendingRequests.clear(); } - _pendingRequests.clear(); } void @@ -678,28 +785,41 @@ LocatorI::invoke(const Ice::LocatorPrxPtr& locator, const RequestPtr& request) Lock sync(*this); if(_locator && _locator != locator) { - request->invoke(_locator); + if(request) + { + request->invoke(_locator); + } } else if(IceUtil::Time::now() < _nextRetry) { - request->invoke(_voidLocator); // Don't retry to find a locator before the retry delay expires + if(request) + { + request->invoke(_voidLocator); // Don't retry to find a locator before the retry delay expires + } } else { _locator = 0; - _pendingRequests.push_back(request); + if(request) + { + _pendingRequests.push_back(request); + } if(_pendingRetryCount == 0) // No request in progress { _pendingRetryCount = _retryCount; try { + for(vector<pair<LookupPrxPtr, LookupReplyPrxPtr> >::const_iterator l = _lookup.begin(); + l != _lookup.end(); ++l) + { #ifdef ICE_CPP11_MAPPING - _lookup->findLocatorAsync(_instanceName, _lookupReply); // Send multicast request. + l->first->findLocatorAsync(_instanceName, l->second); // Send multicast request. #else - _lookup->begin_findLocator(_instanceName, _lookupReply); // Send multicast request. + l->first->begin_findLocator(_instanceName, l->second); // Send multicast request. #endif + } _timer->schedule(ICE_SHARED_FROM_THIS, _timeout); } catch(const Ice::LocalException&) @@ -723,11 +843,15 @@ LocatorI::runTimerTask() { try { + for(vector<pair<LookupPrxPtr, LookupReplyPrxPtr> >::const_iterator l = _lookup.begin(); + l != _lookup.end(); ++l) + { #ifdef ICE_CPP11_MAPPING - _lookup->findLocatorAsync(_instanceName, _lookupReply); // Send multicast request. + l->first->findLocatorAsync(_instanceName, l->second); // Send multicast request. #else - _lookup->begin_findLocator(_instanceName, _lookupReply); // Send multicast request. + l->first->begin_findLocator(_instanceName, l->second); // Send multicast request. #endif + } _timer->schedule(ICE_SHARED_FROM_THIS, _timeout); return; } @@ -737,11 +861,18 @@ LocatorI::runTimerTask() _pendingRetryCount = 0; } - for(vector<RequestPtr>::const_iterator p = _pendingRequests.begin(); p != _pendingRequests.end(); ++p) + if(_pendingRequests.empty()) + { + notify(); + } + else { - (*p)->invoke(_voidLocator); // Send pending requests on void locator. + for(vector<RequestPtr>::const_iterator p = _pendingRequests.begin(); p != _pendingRequests.end(); ++p) + { + (*p)->invoke(_voidLocator); // Send pending requests on void locator. + } + _pendingRequests.clear(); } - _pendingRequests.clear(); _nextRetry = IceUtil::Time::now() + _retryDelay; // Only retry when the retry delay expires } diff --git a/cpp/src/IceLocatorDiscovery/PluginI.h b/cpp/src/IceLocatorDiscovery/PluginI.h deleted file mode 100644 index c87b6a9b438..00000000000 --- a/cpp/src/IceLocatorDiscovery/PluginI.h +++ /dev/null @@ -1,36 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved. -// -// This copy of Ice is licensed to you under the terms described in the -// ICE_LICENSE file included in this distribution. -// -// ********************************************************************** - -#ifndef LOCATOR_DISCOVERY_PLUGIN_I_H -#define LOCATOR_DISCOVERY_PLUGIN_I_H - -#include <Ice/Plugin.h> - -namespace IceLocatorDiscovery -{ - -class PluginI : public Ice::Plugin -{ -public: - - PluginI(const Ice::CommunicatorPtr&); - - virtual void initialize(); - virtual void destroy(); - -private: - - const Ice::CommunicatorPtr _communicator; - Ice::ObjectAdapterPtr _locatorAdapter; - Ice::ObjectAdapterPtr _replyAdapter; -}; - -}; - -#endif |