summaryrefslogtreecommitdiff
path: root/Ivy/IvyWatcher.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ivy/IvyWatcher.cs')
-rw-r--r--Ivy/IvyWatcher.cs261
1 files changed, 135 insertions, 126 deletions
diff --git a/Ivy/IvyWatcher.cs b/Ivy/IvyWatcher.cs
index 8764a28..f239b99 100644
--- a/Ivy/IvyWatcher.cs
+++ b/Ivy/IvyWatcher.cs
@@ -15,8 +15,8 @@ namespace IvyBus
using System.Text.RegularExpressions;
using System.Configuration;
using System.Text;
- using System.Diagnostics;
- using IvyBus.Properties;
+ using System.Diagnostics;
+ using IvyBus.Properties;
/// <summary> IvyWatcher, A private Class for the Ivy rendezvous
/// </summary>
@@ -26,13 +26,14 @@ namespace IvyBus
/// that the broadcast is done using the same socket, which is not a good
/// thing.
/// </remarks>
- internal class IvyWatcher: IDisposable
+ internal class IvyWatcher //: IDisposable
{
private Ivy bus; /* master bus controler */
private int port;
private volatile Thread listenThread;
private IPAddress group;
- private IvyUDPStream stream;
+ private IvyUDPStream stream;
+ private bool ipv6;
/// <summary> creates an Ivy watcher
/// </summary>
@@ -42,38 +43,46 @@ namespace IvyBus
/// </param>
/// <param name='port'>the port number
/// </param>
- internal IvyWatcher(Ivy bus, String domainaddr, int port)
+ internal IvyWatcher(Ivy bus, String domainaddr, int port, bool _ipv6)
{
- int multicast_ttl = 64; // region
+ int multicast_ttl = 64; // region
this.bus = bus;
this.port = port;
+ this.ipv6 = _ipv6;
listenThread = new Thread(new ThreadStart(this.Run));
listenThread.Name = "Ivy UDP Listener Thread";
try
{
group = IPAddress.Parse(domainaddr);
- /* supervision socket */
- // To do reuseaddr we must use a Socket not a udp client
- Socket broadcast = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
- IPEndPoint EPhost = new IPEndPoint(IPAddress.Any, port);
+ /* supervision socket */
+ // To do reuseaddr we must use a Socket not a udp client
+ Socket broadcast = new Socket(ipv6 ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
+ IPEndPoint EPhost = new IPEndPoint(ipv6 ? IPAddress.IPv6Any : IPAddress.Any, port);
broadcast.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast,true);
broadcast.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress,true);
broadcast.Bind(EPhost);
//test isMulticastAddress // TODO better check
- //if ( group.IsIPv6Multicast ) //yes but in IPV4 how to do
- byte[] addr = group.GetAddressBytes();
- if ((addr[0] & 0xf0) == 0xe0)
- {
- broadcast.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, multicast_ttl);
- broadcast.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(group));
-
- }
- // TODO support the Two protocol
- if (bus.protocolVersion == 4)
- stream = new IvyUDPStreamV4(broadcast);
- else
- stream = new IvyUDPStreamV3(broadcast);
+ if (group.IsIPv6Multicast) //IPV6 multicast
+ {
+ broadcast.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.MulticastTimeToLive, multicast_ttl);
+ broadcast.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.AddMembership, new IPv6MulticastOption(group));
+ }
+ else
+ {
+ byte[] addr = group.GetAddressBytes();//yes but in IPV4 how to do better
+ if ((addr[0] & 0xf0) == 0xe0)
+ {
+ broadcast.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, multicast_ttl);
+ broadcast.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(group));
+
+ }
+ }
+ // TODO support the Two protocol
+ if (bus.protocolVersion == 4)
+ stream = new IvyUDPStreamV4(broadcast);
+ else
+ stream = new IvyUDPStreamV3(broadcast);
}
catch (IOException e)
{
@@ -82,95 +91,95 @@ namespace IvyBus
}
/// <summary>
- /// the behaviour of each thread watching the UDP socket.
+ /// the behaviour of each thread watching the UDP socket.
/// </summary>
private void Run()
{
- Ivy.traceProtocol(Resources.IvyWatcher, "beginning of a watcher Thread");
-
- try
- {
- bool running = true;
- while (running)
- {
- int version;
- int appPort;
- string appId;
- string appName;
- IPEndPoint remoteEP;
-
- stream.receiveMsg(out remoteEP, out version, out appPort, out appId, out appName);
- IPAddress remotehost = remoteEP.Address;
-
- Ivy.traceProtocol(Resources.IvyWatcher, Resources.WatcherReceive + Dns.GetHostEntry(remotehost).HostName + ":" + remoteEP.Port);
-
- //TODO if ( !isInDomain( remotehost ) ) continue;
-
- if (version != stream.ProtocolVersion)
- {
- Ivy.traceError(Resources.IvyWatcher, Resources.BadVersion + version + " expected " + stream.ProtocolVersion);
- continue;
- }
-
- /* check if we received our own message. SHOULD ALSO TEST THE HOST */
- if (appId == bus.AppId)
- continue;
- if ((appPort == bus.applicationPort) && (remotehost.Equals(bus.applicationHost)))
- continue;
-
- Ivy.traceProtocol(Resources.IvyWatcher, "reponse au Broadcast de " + Dns.GetHostEntry(remotehost).HostName + ":" + remoteEP.Port + " port " + appPort +
- " version " + version +
- " id " + appId +
- " name " + appName);
-
- try
- {
- Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- IPEndPoint hostEndPoint = new IPEndPoint(remoteEP.Address, appPort);
- socket.Blocking = true;
- socket.Connect(hostEndPoint);
- IvyClient client = new IvyClient(this.bus, socket, appName, appPort);
- client.SendBindings();
- }
- catch (SocketException e)
- {
- Ivy.traceError(Resources.IvyWatcher, Resources.WatcherConnectError + remotehost + " port " + appPort + " \n" + e.Message);
- }
+ Ivy.traceProtocol(Resources.IvyWatcher, "beginning of a watcher Thread");
- } // while
- }
- catch (ObjectDisposedException ex)
- {
- Ivy.traceError(Resources.IvyWatcher, Resources.WatcherSocketClosed + ex.Message);
- }
- catch (SocketException se)
- {
- Ivy.traceError(Resources.IvyWatcher, Resources.WatcherSocketClosed + se.Message);
- }
- catch (IOException ioe)
- {
- Ivy.traceError(Resources.IvyWatcher, Resources.WatcherIOException + ioe.Message);
- }
- Ivy.traceProtocol(Resources.IvyWatcher, "end of a watcher thread");
+ try
+ {
+ bool running = true;
+ while (running)
+ {
+ int version;
+ int appPort;
+ string appId;
+ string appName;
+ IPEndPoint remoteEP;
+
+ stream.receiveMsg(out remoteEP, out version, out appPort, out appId, out appName);
+ IPAddress remotehost = remoteEP.Address;
+
+ Ivy.traceProtocol(Resources.IvyWatcher, Resources.WatcherReceive + Dns.GetHostEntry(remotehost).HostName + ":" + remoteEP.Port);
+
+ //TODO if ( !isInDomain( remotehost ) ) continue;
+
+ if (version != stream.ProtocolVersion)
+ {
+ Ivy.traceError(Resources.IvyWatcher, Resources.BadVersion + version + " expected " + stream.ProtocolVersion);
+ continue;
+ }
+
+ /* check if we received our own message. SHOULD ALSO TEST THE HOST */
+ if (appId == bus.AppId)
+ continue;
+ if ((appPort == bus.applicationPort) && (remotehost.Equals(bus.applicationHost)))
+ continue;
+
+ Ivy.traceProtocol(Resources.IvyWatcher, "reponse au Broadcast de " + Dns.GetHostEntry(remotehost).HostName + ":" + remoteEP.Port + " port " + appPort +
+ " version " + version +
+ " id " + appId +
+ " name " + appName);
+
+ try
+ {
+ Socket socket = new Socket(ipv6 ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+ IPEndPoint hostEndPoint = new IPEndPoint(remoteEP.Address, appPort);
+ socket.Blocking = true;
+ socket.Connect(hostEndPoint);
+ IvyClient client = new IvyClient(this.bus, socket, appName, appPort);
+ client.SendBindings();
+ }
+ catch (SocketException e)
+ {
+ Ivy.traceError(Resources.IvyWatcher, Resources.WatcherConnectError + remotehost + " port " + appPort + " \n" + e.Message);
+ }
+
+ } // while
+ }
+ catch (ObjectDisposedException ex)
+ {
+ Ivy.traceError(Resources.IvyWatcher, Resources.WatcherSocketClosed + ex.Message);
+ }
+ catch (SocketException se)
+ {
+ Ivy.traceError(Resources.IvyWatcher, Resources.WatcherSocketClosed + se.Message);
+ }
+ catch (IOException ioe)
+ {
+ Ivy.traceError(Resources.IvyWatcher, Resources.WatcherIOException + ioe.Message);
+ }
+ Ivy.traceProtocol(Resources.IvyWatcher, "end of a watcher thread");
}
/// <summary> stops the thread waiting on the broadcast socket
/// </summary>
internal virtual void stop()
{
- lock (stream)
+ lock (stream)
{
- Ivy.traceProtocol(Resources.IvyWatcher, "begining stopping an IvyWatcher");
+ Ivy.traceProtocol(Resources.IvyWatcher, "begining stopping an IvyWatcher");
stream.Close();
if (listenThread != null)
{
- // Wait for Thread to end.
- bool term = listenThread.Join(10000);
- if (!term && (listenThread != null)) listenThread.Abort();
+ // Wait for Thread to end.
+ bool term = listenThread.Join(10000);
+ if (!term && (listenThread != null)) listenThread.Abort();
listenThread = null;
}
// it might not even have been created
- Ivy.traceProtocol(Resources.IvyWatcher, "ending stopping an IvyWatcher");
+ Ivy.traceProtocol(Resources.IvyWatcher, "ending stopping an IvyWatcher");
}
}
/// <summary>
@@ -178,39 +187,39 @@ namespace IvyBus
/// </summary>
internal virtual void start()
{
- lock (stream)
+ lock (stream)
{
listenThread.Start();
- IPEndPoint EPhost = new IPEndPoint(group, port);
- stream.sendMsg(EPhost, bus.applicationPort, bus.AppId, bus.AppName);// notifies our arrival on each domain: protocol version + port
+ IPEndPoint EPhost = new IPEndPoint(group, port);
+ stream.sendMsg(EPhost, bus.applicationPort, bus.AppId, bus.AppName);// notifies our arrival on each domain: protocol version + port
}
}
-
-
- #region IDisposable Membres
-
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- // Free other state (managed objects).
- if (stream != null)
- {
- stream.Close();
- stream = null;
- }
- }
- // Free your own state (unmanaged objects).
- // Set large fields to null.
-
- }
-
- #endregion
- }
+ // Not needed for pure managed object ??!!!
+
+ //#region IDisposable Membres
+
+ //public void Dispose()
+ //{
+ // Dispose(true);
+ // GC.SuppressFinalize(this);
+ //}
+
+ //protected virtual void Dispose(bool disposing)
+ //{
+ // if (disposing)
+ // {
+ // // Free other state (managed objects).
+ // if (stream != null)
+ // {
+ // stream.Close();
+ // stream = null;
+ // }
+ // }
+ // // Free your own state (unmanaged objects).
+ // // Set large fields to null.
+
+ //}
+
+ //#endregion
+ }
} \ No newline at end of file