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 /csharp/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 'csharp/src')
-rw-r--r-- | csharp/src/Ice/Network.cs | 10 | ||||
-rw-r--r-- | csharp/src/Ice/PropertyNames.cs | 39 | ||||
-rw-r--r-- | csharp/src/Ice/UdpTransceiver.cs | 8 | ||||
-rw-r--r-- | csharp/src/IceDiscovery/LookupI.cs | 89 | ||||
-rw-r--r-- | csharp/src/IceDiscovery/PluginI.cs | 48 | ||||
-rw-r--r-- | csharp/src/IceLocatorDiscovery/PluginI.cs | 295 |
6 files changed, 362 insertions, 127 deletions
diff --git a/csharp/src/Ice/Network.cs b/csharp/src/Ice/Network.cs index d9172aa086c..babefa65710 100644 --- a/csharp/src/Ice/Network.cs +++ b/csharp/src/Ice/Network.cs @@ -457,7 +457,7 @@ namespace IceInternal try { var indexes = new HashSet<int>(); - foreach(string intf in getInterfacesForMulticast(iface, group)) + foreach(string intf in getInterfacesForMulticast(iface, getProtocolSupport(group))) { int index = getInterfaceIndex(intf, group.AddressFamily); if(!indexes.Contains(index)) @@ -687,6 +687,11 @@ namespace IceInternal setBlock(fd, fd.Blocking); } + public static int getProtocolSupport(IPAddress addr) + { + return addr.AddressFamily == AddressFamily.InterNetwork ? EnableIPv4 : EnableIPv6; + } + public static EndPoint getAddressForServer(string host, int port, int protocol, bool preferIPv6) { if(host.Length == 0) @@ -951,11 +956,10 @@ namespace IceInternal return hosts; } - public static List<string> getInterfacesForMulticast(string intf, IPAddress group) + public static List<string> getInterfacesForMulticast(string intf, int protocol) { List<string> interfaces = new List<string>(); bool ipv4Wildcard = false; - int protocol = group.AddressFamily == AddressFamily.InterNetwork ? EnableIPv4 : EnableIPv6; if(isWildcard(intf, out ipv4Wildcard)) { IPAddress[] addrs = getLocalAddresses(ipv4Wildcard ? EnableIPv4 : protocol, true); diff --git a/csharp/src/Ice/PropertyNames.cs b/csharp/src/Ice/PropertyNames.cs index 5cfc6aaaab6..b5fa1fec421 100644 --- a/csharp/src/Ice/PropertyNames.cs +++ b/csharp/src/Ice/PropertyNames.cs @@ -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! @@ -504,6 +504,43 @@ namespace IceInternal new Property(@"^IceGridAdmin\.Discovery\.Reply\.ThreadPool\.ThreadIdleTime$", false, null), new Property(@"^IceGridAdmin\.Discovery\.Reply\.ThreadPool\.ThreadPriority$", false, null), new Property(@"^IceGridAdmin\.Discovery\.Reply\.MessageSizeMax$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.ACM\.Timeout$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.ACM\.Heartbeat$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.ACM\.Close$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.ACM$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.AdapterId$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.Endpoints$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.Locator\.EndpointSelection$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.Locator\.ConnectionCached$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.Locator\.PreferSecure$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.Locator\.LocatorCacheTimeout$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.Locator\.InvocationTimeout$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.Locator\.Locator$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.Locator\.Router$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.Locator\.CollocationOptimized$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.Locator\.Context\.[^\s]+$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.Locator$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.PublishedEndpoints$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.ReplicaGroupId$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.Router\.EndpointSelection$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.Router\.ConnectionCached$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.Router\.PreferSecure$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.Router\.LocatorCacheTimeout$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.Router\.InvocationTimeout$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.Router\.Locator$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.Router\.Router$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.Router\.CollocationOptimized$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.Router\.Context\.[^\s]+$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.Router$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.ProxyOptions$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.ThreadPool\.Size$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.ThreadPool\.SizeMax$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.ThreadPool\.SizeWarn$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.ThreadPool\.StackSize$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.ThreadPool\.Serialize$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.ThreadPool\.ThreadIdleTime$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.ThreadPool\.ThreadPriority$", false, null), + new Property(@"^IceGridAdmin\.Discovery\.Locator\.MessageSizeMax$", false, null), new Property(@"^IceGridAdmin\.Trace\.Observers$", false, null), new Property(@"^IceGridAdmin\.Trace\.SaveToRegistry$", false, null), null diff --git a/csharp/src/Ice/UdpTransceiver.cs b/csharp/src/Ice/UdpTransceiver.cs index 0b469bba3ac..897ca80a9a6 100644 --- a/csharp/src/Ice/UdpTransceiver.cs +++ b/csharp/src/Ice/UdpTransceiver.cs @@ -586,11 +586,10 @@ namespace IceInternal info.remotePort = Network.endpointPort(remoteEndpoint); } } + info.rcvSize = Network.getRecvBufferSize(_fd); + info.sndSize = Network.getSendBufferSize(_fd); } - info.rcvSize = Network.getRecvBufferSize(_fd); - info.sndSize = Network.getSendBufferSize(_fd); - if(_mcastAddr != null) { info.mcastAddress = Network.endpointAddressToString(_mcastAddr); @@ -660,7 +659,8 @@ namespace IceInternal } else { - intfs = Network.getInterfacesForMulticast(_mcastInterface, _mcastAddr.Address); + intfs = Network.getInterfacesForMulticast(_mcastInterface, + Network.getProtocolSupport(_mcastAddr.Address)); } if(intfs.Count != 0) { diff --git a/csharp/src/IceDiscovery/LookupI.cs b/csharp/src/IceDiscovery/LookupI.cs index ee1775bb444..14dfbdd9f36 100644 --- a/csharp/src/IceDiscovery/LookupI.cs +++ b/csharp/src/IceDiscovery/LookupI.cs @@ -12,6 +12,8 @@ namespace IceDiscovery using System; using System.Collections.Generic; using System.Threading.Tasks; + using System.Text; + using System.Diagnostics; class Request<T> { @@ -154,17 +156,77 @@ namespace IceDiscovery public LookupI(LocatorRegistryI registry, LookupPrx lookup, Ice.Properties properties) { _registry = registry; - _lookup = lookup; _timeout = properties.getPropertyAsIntWithDefault("IceDiscovery.Timeout", 300); _retryCount = properties.getPropertyAsIntWithDefault("IceDiscovery.RetryCount", 3); _latencyMultiplier = properties.getPropertyAsIntWithDefault("IceDiscovery.LatencyMultiplier", 1); _domainId = properties.getProperty("IceDiscovery.DomainId"); _timer = IceInternal.Util.getInstance(lookup.ice_getCommunicator()).timer(); + + try + { + lookup.ice_getConnection(); + } + catch(Ice.LocalException ex) + { + StringBuilder b = new StringBuilder(); + b.Append("IceDiscovery is unable to establish a multicast connection:\n"); + b.Append("proxy = "); + b.Append(lookup.ToString()); + b.Append('\n'); + b.Append(ex.ToString()); + throw new Ice.PluginInitializationException(b.ToString()); + } + + // + // Create one lookup proxy per endpoint from the given proxy. We want to send a multicast + // datagram on each endpoint. + // + var single = new Ice.Endpoint[1]; + foreach(var endpt in lookup.ice_getEndpoints()) + { + try + { + single[0] = endpt; + LookupPrx l = (LookupPrx)lookup.ice_endpoints(single); + l.ice_getConnection(); + _lookup[(LookupPrx)lookup.ice_endpoints(single)] = null; + } + catch(Ice.LocalException) + { + // Ignore + } + } + Debug.Assert(_lookup.Count > 0); } public void setLookupReply(LookupReplyPrx lookupReply) { - _lookupReply = lookupReply; + // + // Use a lookup reply proxy whose adress matches the interface used to send multicast datagrams. + // + var single = new Ice.Endpoint[1]; + foreach(var key in new List<LookupPrx>(_lookup.Keys)) + { + var info = (Ice.UDPEndpointInfo)key.ice_getEndpoints()[0].getInfo(); + if(info.mcastInterface.Length > 0) + { + foreach(var q in lookupReply.ice_getEndpoints()) + { + var r = q.getInfo(); + if(r is Ice.IPEndpointInfo && ((Ice.IPEndpointInfo)r).host.Equals(info.mcastInterface)) + { + single[0] = q; + _lookup[key] = (LookupReplyPrx)lookupReply.ice_endpoints(single); + } + } + } + + if(_lookup[key] == null) + { + // Fallback: just use the given lookup reply proxy if no matching endpoint found. + _lookup[key] = lookupReply; + } + } } public override void findObjectById(string domainId, Ice.Identity id, LookupReplyPrx reply, @@ -234,7 +296,10 @@ namespace IceDiscovery { try { - _lookup.findObjectByIdAsync(_domainId, id, _lookupReply); + foreach(var l in _lookup) + { + l.Key.findObjectByIdAsync(_domainId, id, l.Value); + } _timer.schedule(request, _timeout); } catch(Ice.LocalException) @@ -263,7 +328,10 @@ namespace IceDiscovery { try { - _lookup.findAdapterByIdAsync(_domainId, adapterId, _lookupReply); + foreach(var l in _lookup) + { + l.Key.findAdapterByIdAsync(_domainId, adapterId, l.Value); + } _timer.schedule(request, _timeout); } catch(Ice.LocalException) @@ -323,7 +391,10 @@ namespace IceDiscovery { try { - _lookup.findObjectByIdAsync(_domainId, request.getId(), _lookupReply); + foreach(var l in _lookup) + { + l.Key.findObjectByIdAsync(_domainId, request.getId(), l.Value); + } _timer.schedule(request, _timeout); return; } @@ -352,7 +423,10 @@ namespace IceDiscovery { try { - _lookup.findAdapterByIdAsync(_domainId, request.getId(), _lookupReply); + foreach(var l in _lookup) + { + l.Key.findAdapterByIdAsync(_domainId, request.getId(), l.Value); + } _timer.schedule(request, _timeout); return; } @@ -378,8 +452,7 @@ namespace IceDiscovery } private LocatorRegistryI _registry; - private readonly LookupPrx _lookup; - private LookupReplyPrx _lookupReply; + private Dictionary<LookupPrx, LookupReplyPrx> _lookup = new Dictionary<LookupPrx, LookupReplyPrx>(); private readonly int _timeout; private readonly int _retryCount; private readonly int _latencyMultiplier; diff --git a/csharp/src/IceDiscovery/PluginI.cs b/csharp/src/IceDiscovery/PluginI.cs index 5883dabeaf5..f633d3a7f2d 100644 --- a/csharp/src/IceDiscovery/PluginI.cs +++ b/csharp/src/IceDiscovery/PluginI.cs @@ -57,16 +57,28 @@ namespace IceDiscovery } properties.setProperty("IceDiscovery.Multicast.Endpoints", s.ToString()); } - if(properties.getProperty("IceDiscovery.Reply.Endpoints").Length == 0) + + string lookupEndpoints = properties.getProperty("IceDiscovery.Lookup"); + if(lookupEndpoints.Length == 0) { - StringBuilder s = new StringBuilder(); - s.Append("udp"); - if(intf.Length != 0) + int protocol = ipv4 && !preferIPv6 ? IceInternal.Network.EnableIPv4 : IceInternal.Network.EnableIPv6; + var interfaces = IceInternal.Network.getInterfacesForMulticast(intf, protocol); + foreach(string p in interfaces) { - s.Append(" -h \"").Append(intf).Append("\""); + if(p != interfaces[0]) + { + lookupEndpoints += ":"; + } + lookupEndpoints += "udp -h \"" + address + "\" -p " + port + " --interface \"" + p + "\""; } - properties.setProperty("IceDiscovery.Reply.Endpoints", s.ToString()); } + + if(properties.getProperty("IceDiscovery.Reply.Endpoints").Length == 0) + { + properties.setProperty("IceDiscovery.Reply.Endpoints", + "udp -h " + (intf.Length == 0 ? "*" : "\"" + intf + "\"")); + } + if(properties.getProperty("IceDiscovery.Locator.Endpoints").Length == 0) { properties.setProperty("IceDiscovery.Locator.AdapterId", Guid.NewGuid().ToString()); @@ -83,32 +95,8 @@ namespace IceDiscovery Ice.LocatorRegistryPrx locatorRegistryPrx = Ice.LocatorRegistryPrxHelper.uncheckedCast( _locatorAdapter.addWithUUID(locatorRegistry)); - string lookupEndpoints = properties.getProperty("IceDiscovery.Lookup"); - if(lookupEndpoints.Length == 0) - { - lookupEndpoints = "udp -h \"" + address + "\" -p " + port; - if(intf.Length > 0) - { - lookupEndpoints += " --interface \"" + intf + "\""; - } - } - Ice.ObjectPrx lookupPrx = _communicator.stringToProxy("IceDiscovery/Lookup -d:" + lookupEndpoints); lookupPrx = lookupPrx.ice_collocationOptimized(false); - try - { - lookupPrx.ice_getConnection(); - } - catch(Ice.LocalException ex) - { - StringBuilder b = new StringBuilder(); - b.Append("IceDiscovery is unable to establish a multicast connection:\n"); - b.Append("proxy = "); - b.Append(lookupPrx.ToString()); - b.Append('\n'); - b.Append(ex.ToString()); - throw new Ice.PluginInitializationException(b.ToString()); - } // // Add lookup and lookup reply Ice objects diff --git a/csharp/src/IceLocatorDiscovery/PluginI.cs b/csharp/src/IceLocatorDiscovery/PluginI.cs index 7e728d4b2e8..a3a32cb3c7f 100644 --- a/csharp/src/IceLocatorDiscovery/PluginI.cs +++ b/csharp/src/IceLocatorDiscovery/PluginI.cs @@ -12,17 +12,24 @@ namespace IceLocatorDiscovery using System; using System.Collections.Generic; using System.Diagnostics; + using System.Threading; using System.Threading.Tasks; + using System.Text; public sealed class PluginFactory : Ice.PluginFactory { public Ice.Plugin create(Ice.Communicator communicator, string name, string[] args) { - return new PluginI(communicator); + return new PluginI(name, communicator); } } + public interface Plugin : Ice.Plugin + { + List<Ice.LocatorPrx> getLocators(string instanceName, int waitTime); + } + internal class Request : TaskCompletionSource<Ice.Object_Ice_invokeResult> { public Request(LocatorI locator, @@ -132,24 +139,85 @@ namespace IceLocatorDiscovery internal class LocatorI : Ice.BlobjectAsync, IceInternal.TimerTask { public - LocatorI(LookupPrx lookup, Ice.Properties properties, string instanceName, Ice.LocatorPrx voidLocator) + LocatorI(string name, LookupPrx lookup, Ice.Properties properties, string instanceName, + Ice.LocatorPrx voidLocator) { - _lookup = lookup; - _timeout = properties.getPropertyAsIntWithDefault("IceLocatorDiscovery.Timeout", 300); - _retryCount = properties.getPropertyAsIntWithDefault("IceLocatorDiscovery.RetryCount", 3); - _retryDelay = properties.getPropertyAsIntWithDefault("IceLocatorDiscovery.RetryDelay", 2000); + _timeout = properties.getPropertyAsIntWithDefault(name + ".Timeout", 300); + _retryCount = properties.getPropertyAsIntWithDefault(name + ".RetryCount", 3); + _retryDelay = properties.getPropertyAsIntWithDefault(name + ".RetryDelay", 2000); _timer = IceInternal.Util.getInstance(lookup.ice_getCommunicator()).timer(); _instanceName = instanceName; _warned = false; _locator = lookup.ice_getCommunicator().getDefaultLocator(); _voidLocator = voidLocator; _pendingRetryCount = 0; + + try + { + lookup.ice_getConnection(); + } + catch(Ice.LocalException ex) + { + StringBuilder b = new StringBuilder(); + b.Append("IceLocatorDiscovery is unable to establish a multicast connection:\n"); + b.Append("proxy = "); + b.Append(lookup.ToString()); + b.Append('\n'); + b.Append(ex.ToString()); + throw new Ice.PluginInitializationException(b.ToString()); + } + + // + // Create one lookup proxy per endpoint from the given proxy. We want to send a multicast + // datagram on each endpoint. + // + var single = new Ice.Endpoint[1]; + foreach(var endpt in lookup.ice_getEndpoints()) + { + try + { + single[0] = endpt; + LookupPrx l = (LookupPrx)lookup.ice_endpoints(single); + l.ice_getConnection(); + _lookup[(LookupPrx)lookup.ice_endpoints(single)] = null; + } + catch(Ice.LocalException) + { + // Ignore + } + } + Debug.Assert(_lookup.Count > 0); } public void setLookupReply(LookupReplyPrx lookupReply) { - _lookupReply = lookupReply; + // + // Use a lookup reply proxy whose adress matches the interface used to send multicast datagrams. + // + var single = new Ice.Endpoint[1]; + foreach(var key in new List<LookupPrx>(_lookup.Keys)) + { + var info = (Ice.UDPEndpointInfo)key.ice_getEndpoints()[0].getInfo(); + if(info.mcastInterface.Length > 0) + { + foreach(var q in lookupReply.ice_getEndpoints()) + { + var r = q.getInfo(); + if(r is Ice.IPEndpointInfo && ((Ice.IPEndpointInfo)r).host.Equals(info.mcastInterface)) + { + single[0] = q; + _lookup[key] = (LookupReplyPrx)lookupReply.ice_endpoints(single); + } + } + } + + if(_lookup[key] == null) + { + // Fallback: just use the given lookup reply proxy if no matching endpoint found. + _lookup[key] = lookupReply; + } + } } public override Task<Ice.Object_Ice_invokeResult> @@ -163,6 +231,49 @@ namespace IceLocatorDiscovery } } + public List<Ice.LocatorPrx> + getLocators(String instanceName, int waitTime) + { + // + // Clear locators from previous search. + // + lock(this) + { + _locators.Clear(); + } + + // + // Find a locator + // + invoke(null, null); + + // + // Wait for responses + // + if(instanceName.Length == 0) + { + Thread.Sleep(waitTime); + } + else + { + lock(this) + { + while(!_locators.ContainsKey(instanceName) && _pendingRetryCount > 0) + { + Monitor.Wait(this, waitTime); + } + } + } + + // + // Return found locators + // + lock(this) + { + return new List<Ice.LocatorPrx>(_locators.Values); + } + } + public void foundLocator(Ice.LocatorPrx locator) { @@ -178,7 +289,8 @@ namespace IceLocatorDiscovery // If we already have a locator assigned, ensure the given locator // has the same identity, otherwise ignore it. // - if(_locator != null && !locator.ice_getIdentity().category.Equals(_locator.ice_getIdentity().category)) + if(_pendingRequests.Count > 0 && + _locator != null && !locator.ice_getIdentity().category.Equals(_locator.ice_getIdentity().category)) { if(!_warned) { @@ -202,13 +314,22 @@ namespace IceLocatorDiscovery _pendingRetryCount = 0; } - if(_locator != null) + Ice.LocatorPrx l = null; + if(_pendingRequests.Count == 0) + { + _locators.TryGetValue(locator.ice_getIdentity().category, out _locator); + } + else + { + l = _locator; + } + if(l != null) { // // We found another locator replica, append its endpoints to the // current locator proxy endpoints. // - List<Ice.Endpoint> newEndpoints = new List<Ice.Endpoint>(_locator.ice_getEndpoints()); + List<Ice.Endpoint> newEndpoints = new List<Ice.Endpoint>(l.ice_getEndpoints()); foreach(Ice.Endpoint p in locator.ice_getEndpoints()) { // @@ -228,25 +349,35 @@ namespace IceLocatorDiscovery newEndpoints.Add(p); } } - _locator = (Ice.LocatorPrx) _locator.ice_endpoints(newEndpoints.ToArray()); + l = (Ice.LocatorPrx)l.ice_endpoints(newEndpoints.ToArray()); } else { - _locator = locator; + l = locator; + } + + if(_pendingRequests.Count == 0) + { + _locators[locator.ice_getIdentity().category] = l; + Monitor.Pulse(this); + } + else + { + _locator = l; if(_instanceName.Length == 0) { _instanceName = _locator.ice_getIdentity().category; // Stick to the first locator } - } - // - // Send pending requests if any. - // - foreach(Request req in _pendingRequests) - { - req.invoke(_locator); + // + // Send pending requests if any. + // + foreach(Request req in _pendingRequests) + { + req.invoke(_locator); + } + _pendingRequests.Clear(); } - _pendingRequests.Clear(); } } @@ -257,24 +388,36 @@ namespace IceLocatorDiscovery { if(_locator != null && _locator != locator) { - request.invoke(_locator); + if(request != null) + { + request.invoke(_locator); + } } else if(IceInternal.Time.currentMonotonicTimeMillis() < _nextRetry) { - request.invoke(_voidLocator); // Don't retry to find a locator before the retry delay expires + if(request != null) + { + request.invoke(_voidLocator); // Don't retry to find a locator before the retry delay expires + } } else { _locator = null; - _pendingRequests.Add(request); + if(request != null) + { + _pendingRequests.Add(request); + } if(_pendingRetryCount == 0) // No request in progress { _pendingRetryCount = _retryCount; try { - _lookup.findLocatorAsync(_instanceName, _lookupReply); // Send multicast request. + foreach(var l in _lookup) + { + l.Key.findLocatorAsync(_instanceName, l.Value); // Send multicast request. + } _timer.schedule(this, _timeout); } catch(Ice.LocalException) @@ -300,7 +443,10 @@ namespace IceLocatorDiscovery { try { - _lookup.findLocatorAsync(_instanceName, _lookupReply); // Send multicast request + foreach(var l in _lookup) + { + l.Key.findLocatorAsync(_instanceName, l.Value); // Send multicast request + } _timer.schedule(this, _timeout); return; } @@ -319,7 +465,7 @@ namespace IceLocatorDiscovery } } - private LookupPrx _lookup; + private Dictionary<LookupPrx, LookupReplyPrx> _lookup = new Dictionary<LookupPrx, LookupReplyPrx>(); private int _timeout; private IceInternal.Timer _timer; private int _retryCount; @@ -327,9 +473,9 @@ namespace IceLocatorDiscovery private string _instanceName; private bool _warned; - private LookupReplyPrx _lookupReply; private Ice.LocatorPrx _locator; private Ice.LocatorPrx _voidLocator; + private Dictionary<string, Ice.LocatorPrx> _locators = new Dictionary<string, Ice.LocatorPrx>(); private int _pendingRetryCount; private List<Request> _pendingRequests = new List<Request>(); @@ -352,11 +498,12 @@ namespace IceLocatorDiscovery private LocatorI _locator; } - class PluginI : Ice.Plugin + internal class PluginI : Ice.Plugin { public - PluginI(Ice.Communicator communicator) + PluginI(string name, Ice.Communicator communicator) { + _name = name; _communicator = communicator; } @@ -370,85 +517,63 @@ namespace IceLocatorDiscovery 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").Length == 0) + string lookupEndpoints = properties.getProperty(_name + ".Lookup"); + if(lookupEndpoints.Length == 0) { - System.Text.StringBuilder s = new System.Text.StringBuilder(); - s.Append("udp"); - if(intf.Length > 0) + int protocol = ipv4 && !preferIPv6 ? IceInternal.Network.EnableIPv4 : IceInternal.Network.EnableIPv6; + var interfaces = IceInternal.Network.getInterfacesForMulticast(intf, protocol); + foreach(string p in interfaces) { - s.Append(" -h \""); - s.Append(intf); - s.Append("\""); + if(p != interfaces[0]) + { + lookupEndpoints += ":"; + } + lookupEndpoints += "udp -h \"" + address + "\" -p " + port + " --interface \"" + p + "\""; } - properties.setProperty("IceLocatorDiscovery.Reply.Endpoints", s.ToString()); } - if(properties.getProperty("IceLocatorDiscovery.Locator.Endpoints").Length == 0) + + if(properties.getProperty(_name + ".Reply.Endpoints").Length == 0) { - properties.setProperty("IceLocatorDiscovery.Locator.AdapterId", Guid.NewGuid().ToString()); + properties.setProperty(_name + ".Reply.Endpoints", + "udp -h " + (intf.Length == 0 ? "*" : "\"" + intf + "\"")); } - _replyAdapter = _communicator.createObjectAdapter("IceLocatorDiscovery.Reply"); - _locatorAdapter = _communicator.createObjectAdapter("IceLocatorDiscovery.Locator"); + if(properties.getProperty(_name + ".Locator.Endpoints").Length == 0) + { + properties.setProperty(_name + ".Locator.AdapterId", Guid.NewGuid().ToString()); + } + + _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(null); _locatorAdapter.setLocator(null); - string lookupEndpoints = properties.getProperty("IceLocatorDiscovery.Lookup"); - if(lookupEndpoints.Length == 0) - { - System.Text.StringBuilder s = new System.Text.StringBuilder(); - s.Append("udp -h \""); - s.Append(address); - s.Append("\" -p "); - s.Append(port); - if(intf.Length > 0) - { - s.Append(" --interface \""); - s.Append(intf); - s.Append("\""); - } - lookupEndpoints = s.ToString(); - } - Ice.ObjectPrx lookupPrx = _communicator.stringToProxy("IceLocatorDiscovery/Lookup -d:" + lookupEndpoints); lookupPrx = lookupPrx.ice_collocationOptimized(false); // No colloc optimization for the multicast proxy! - try - { - lookupPrx.ice_getConnection(); // Ensure we can establish a connection to the multicast proxy - } - catch (Ice.LocalException ex) - { - System.Text.StringBuilder s = new System.Text.StringBuilder(); - s.Append("IceLocatorDiscovery is unable to establish a multicast connection:\n"); - s.Append("proxy = "); - s.Append(lookupPrx.ToString()); - s.Append("\n"); - s.Append(ex); - throw new Ice.PluginInitializationException(s.ToString()); - } Ice.LocatorPrx voidLo = Ice.LocatorPrxHelper.uncheckedCast(_locatorAdapter.addWithUUID(new VoidLocatorI())); - string instanceName = properties.getProperty("IceLocatorDiscovery.InstanceName"); + string instanceName = properties.getProperty(_name + ".InstanceName"); Ice.Identity id = new Ice.Identity(); id.name = "Locator"; id.category = instanceName.Length > 0 ? instanceName : Guid.NewGuid().ToString(); - LocatorI locator = new LocatorI(LookupPrxHelper.uncheckedCast(lookupPrx), properties, instanceName, voidLo); - _communicator.setDefaultLocator(Ice.LocatorPrxHelper.uncheckedCast(_locatorAdapter.addWithUUID(locator))); + _locator = new LocatorI(_name, LookupPrxHelper.uncheckedCast(lookupPrx), properties, instanceName, voidLo); + _communicator.setDefaultLocator(Ice.LocatorPrxHelper.uncheckedCast(_locatorAdapter.addWithUUID(_locator))); - Ice.ObjectPrx lookupReply = _replyAdapter.addWithUUID(new LookupReplyI(locator)).ice_datagram(); - locator.setLookupReply(LookupReplyPrxHelper.uncheckedCast(lookupReply)); + Ice.ObjectPrx lookupReply = _replyAdapter.addWithUUID(new LookupReplyI(_locator)).ice_datagram(); + _locator.setLookupReply(LookupReplyPrxHelper.uncheckedCast(lookupReply)); _replyAdapter.activate(); _locatorAdapter.activate(); @@ -461,8 +586,16 @@ namespace IceLocatorDiscovery _locatorAdapter.destroy(); } + List<Ice.LocatorPrx> + getLocators(string instanceName, int waitTime) + { + return _locator.getLocators(instanceName, waitTime); + } + + private string _name; private Ice.Communicator _communicator; private Ice.ObjectAdapter _locatorAdapter; private Ice.ObjectAdapter _replyAdapter; + private LocatorI _locator; } } |