summaryrefslogtreecommitdiff
path: root/csharp/src
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2017-03-01 19:42:52 +0100
committerBenoit Foucher <benoit@zeroc.com>2017-03-01 19:42:52 +0100
commit0a57f0b1841f51bc45ff2adc9ac19e114d695e43 (patch)
tree2ecab85164a70618fc0f861058f97194cb4e797e /csharp/src
parentUWP build failure (diff)
downloadice-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.cs10
-rw-r--r--csharp/src/Ice/PropertyNames.cs39
-rw-r--r--csharp/src/Ice/UdpTransceiver.cs8
-rw-r--r--csharp/src/IceDiscovery/LookupI.cs89
-rw-r--r--csharp/src/IceDiscovery/PluginI.cs48
-rw-r--r--csharp/src/IceLocatorDiscovery/PluginI.cs295
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;
}
}