Example #1
0
        /// <summary>
        /// Dispose per the IDisposable pattern
        /// </summary>
        public void Dispose()
        {
            GC.SuppressFinalize(this);

            if (!disposed)
            {
                disposed = true;
                if (sock != null)
                {
                    // if we are using a reflector, send a tear-down message
                    if (!multicastEP.Equals(nextHopEP))
                    {
                        try
                        {
                            if (joiner != null)
                            {
                                joiner.Terminate();
                            }

                            // send a LEAVE message; this might get lost, but that doesn't matter
                            // because the reflector wil time out.
                            UdpSender           sender  = new UdpSender(nextHopEP, 64);
                            UdpReflectorMessage message = new UdpReflectorMessage(UdpReflectorMessageType.LEAVE, multicastEP);

                            sender.Send(message.ToBufferChunk());
                            sender.Dispose();
                        }
                        catch (Exception) { }
                    }

                    LstSocks.Socket.ReleaseSharedSocket(nextHopEP, sock);
                    sock = null;
                }
            }
        }
Example #2
0
        /// <summary>
        /// Constructor that binds this object instance to an IPEndPoint.  If you need to change settings dynamically, Dispose and recreate a new object.
        /// </summary>
        /// <param name="endPoint">IPEndPoint where to send the multicast packets -- should be in range 224.0.0.0 to 239.255.255.255</param>
        /// <param name="timeToLive">ushort Time To Live of the packets -- how many routers will we cross -- set to 2 for local or testing</param>
        public UdpSender(System.Net.IPEndPoint endPoint, ushort timeToLive)
        {
            this.endPoint = endPoint;

            LstSocks.Socket.SockInterfacePair sip = LstSocks.Socket.GetSharedSocket(endPoint);
            this.sock = sip.sock;
            this.externalInterface = sip.extInterface;

            if (Utility.IsMulticast(endPoint.Address))
            {
                SocketOptionLevel sOL = SocketOptionLevel.IP;
                if (endPoint.AddressFamily == AddressFamily.InterNetworkV6)
                {
                    sOL = SocketOptionLevel.IPv6;
                }
                // Set the TTL
                sock.SetSocketOption(sOL, SocketOptionName.MulticastTimeToLive, timeToLive);
                // Enable Multicast Loopback
                sock.SetSocketOption(sOL, SocketOptionName.MulticastLoopback, 1);
            }
            else
            {
                // Enable Unicast Loopback
                echoEndPoint = new IPEndPoint(externalInterface, endPoint.Port);
            }
        }
Example #3
0
        /// <summary>
        /// Constructor that binds this object instance to an IPEndPoint.  If you need to change settings dynamically, Dispose and recreate a new object.
        /// </summary>
        /// <param name="endPoint">IPEndPoint where to send the multicast packets -- should be in range 224.0.0.0 to 239.255.255.255</param>
        /// <param name="timeToLive">ushort Time To Live of the packets -- how many routers will we cross -- set to 2 for local or testing</param>
        public UdpSender(System.Net.IPEndPoint destEndPoint, ushort timeToLive)
        {
            this.endPoint = destEndPoint;

            LstSocks.Socket.SockInterfacePair sip = LstSocks.Socket.GetSharedSocket(destEndPoint);
            this.sock = sip.sock;
            this.localRoutingInterface = sip.extInterface;

            if (Utility.IsMulticast(destEndPoint.Address))
            {
                SocketOptionLevel sOL = SocketOptionLevel.IP;
                if (destEndPoint.AddressFamily == AddressFamily.InterNetworkV6)
                {
                    sOL = SocketOptionLevel.IPv6;
                }
                // Set the TTL
                sock.SetSocketOption(sOL, SocketOptionName.MulticastTimeToLive, timeToLive);
                // Enable Multicast Loopback
                sock.SetSocketOption(sOL, SocketOptionName.MulticastLoopback, 1);
            }
            else
            {
                // Enable Unicast Loopback
                /// Note: If we didn't also instantiate a UdpListener, the socket won't have been bound
                /// to a local interface.  Specifically this comes up when we use the UdpSender to transmit
                /// reports to a diagnostic server.  In this case the loopback is not needed anyway.
                IPEndPoint localEndpoint = (IPEndPoint)sock.LocalEndPoint;
                if (localEndpoint != null)
                {
                    echoEndPoint = new IPEndPoint(localRoutingInterface, localEndpoint.Port);
                }
            }
        }
Example #4
0
 internal asyncReceiveState(MSR.LST.Net.Sockets.Socket sock, BufferChunk bufferChunk, Queue queue, ReceivedFromCallback receivedFromCallback)
 {
     this.sock                 = sock;
     this.bufferChunk          = bufferChunk;
     this.queue                = queue;
     this.receivedFromCallback = receivedFromCallback;
 }
Example #5
0
        /// <summary>
        /// Constructor that binds this object instance to an IPEndPoint.  If you need to change IPEndPoint dynamically, Dispose and recreate a new object.
        /// </summary>
        /// <param name="endPoint">IPEndPoint where we should be listening for IP Multicast packets.</param>
        /// <param name="TimeoutMilliseconds">Milliseconds before lack of a packet == a Network Timeout</param>
        /// <example>
        /// ...
        /// MulticastUdpListener mcListener = new MulticastUdpListener(endPoint1);
        /// mcListener.Receive(packetBuffer);
        /// mcListener.Displose();
        ///
        /// MulticastUdpListener mcListener = new MulticastUdpListener(endPoint2);
        /// mcListener.Receive(packetBuffer);
        /// mcListener.Displose();
        ///
        /// mcListener = null;
        /// ...
        /// </example>
        public UdpListener(System.Net.IPEndPoint endPoint, int timeoutMilliseconds)
        {
            LstSocks.Socket.SockInterfacePair sip = LstSocks.Socket.GetSharedSocket(endPoint);
            this.sock = sip.sock;
            this.externalInterface = sip.extInterface;
            this.ep = endPoint;

            lock (sip)
            {
                if (!sip.Initialized)
                {
                    try
                    {
                        // Set the timeout on the socket
                        if (timeoutMilliseconds > 0)
                        {
                            sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, timeoutMilliseconds);
                        }

                        // Set the socket to send & receive from this endpoint
                        sock.Bind(new IPEndPoint(externalInterface, endPoint.Port));

                        // Make room for 80 packets plus some overhead
                        sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, 1500 * 80);

                        if (Utility.IsMulticast(endPoint.Address))
                        {
                            if (endPoint.AddressFamily == AddressFamily.InterNetworkV6)
                            {
                                // Join the IPv6 Multicast group
                                sock.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.AddMembership,
                                                     new IPv6MulticastOption(endPoint.Address));
                            }
                            else
                            {
                                // Join the IPv4 Multicast group
                                sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership,
                                                     new MulticastOption(endPoint.Address));
                            }
                        }

                        sip.Initialized = true;
                    }
                    catch
                    {
                        this.Dispose();
                        throw;
                    }
                }
            }
        }
Example #6
0
        /// <summary>
        /// Dispose per the IDisposable pattern
        /// </summary>
        public void Dispose()
        {
            GC.SuppressFinalize(this);

            if (!disposed)
            {
                disposed = true;
                if (sock != null)
                {
                    LstSocks.Socket.ReleaseSharedSocket(ep, sock);
                    sock = null;
                }
            }
        }
Example #7
0
        // Apparently binding to the same ports on UDPSender and UDPListener causes problems in unicast.
        // Sharing the socket though, allows us to tunnel through firewalls as data is sent and received
        // on the same  endpoint.
        // This region of code enables sharing sockets between the two classes.

        internal static SockInterfacePair GetSharedSocket(IPEndPoint endPoint)
        {
            lock(socks)
            {
                object sockObj = socks[endPoint];
                if( sockObj != null )
                {
                    SockInterfacePair sip = (SockInterfacePair)sockObj;
                    ++sip.sock.refCount;
                    return sip;
                }
                else
                {
                    // Create the socket
                    LstSocks.Socket sock = new LstSocks.Socket(endPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);

                    // Get the External Interface, save it for future use
                    IPAddress externalInterface = Utility.GetLocalRoutingInterface(endPoint.Address);

                    if (externalInterface == null)
                    {
                        // Pri3: Do something more helpful here
                        throw new Exception("Unable to find a local routing interface, is no network present?");
                    }

                    if( Utility.IsMulticast(endPoint.Address) )
                    {
                        // Allow multiple binds to this socket, as it will still function properly
                        //  (this is only the case if it is a multicast socket.  Unicast sockets fail to
                        //   receive all data on all sockets)
                        sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, -1);

                        // We don't join the multicast group here, because we may not want to listen
                        // to our own data (halfing our throughput).  jasonv - 10/28/2004
                    }

                    // Add the socket to the hashtable
                    SockInterfacePair sip = new SockInterfacePair();
                    sip.sock = sock;
                    sip.extInterface = externalInterface;
                    socks.Add(endPoint, sip);

                    // Increase the socket's reference count
                    ++sock.refCount;

                    return sip;
                }
            }
        }
Example #8
0
        // Apparently binding to the same ports on UDPSender and UDPListener causes problems in unicast.
        // Sharing the socket though, allows us to tunnel through firewalls as data is sent and received
        // on the same  endpoint.
        // This region of code enables sharing sockets between the two classes.

        internal static SockInterfacePair GetSharedSocket(IPEndPoint endPoint)
        {
            lock (socks)
            {
                object sockObj = socks[endPoint];
                if (sockObj != null)
                {
                    SockInterfacePair sip = (SockInterfacePair)sockObj;
                    ++sip.sock.refCount;
                    return(sip);
                }
                else
                {
                    // Create the socket
                    LstSocks.Socket sock = new LstSocks.Socket(endPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);

                    // Get the External Interface, save it for future use
                    IPAddress externalInterface = Utility.GetLocalRoutingInterface(endPoint.Address);

                    if (externalInterface == null)
                    {
                        // Pri3: Do something more helpful here
                        throw new Exception(Strings.UnableToFindLocalRoutingInterface);
                    }

                    if (Utility.IsMulticast(endPoint.Address))
                    {
                        // Allow multiple binds to this socket, as it will still function properly
                        //  (this is only the case if it is a multicast socket.  Unicast sockets fail to
                        //   receive all data on all sockets)
                        sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, -1);

                        // We don't join the multicast group here, because we may not want to listen
                        // to our own data (halfing our throughput).  jasonv - 10/28/2004
                    }

                    // Add the socket to the hashtable
                    SockInterfacePair sip = new SockInterfacePair();
                    sip.sock         = sock;
                    sip.extInterface = externalInterface;
                    socks.Add(endPoint, sip);

                    // Increase the socket's reference count
                    ++sock.refCount;

                    return(sip);
                }
            }
        }
Example #9
0
        /// <summary>
        /// This constructor is for use with a unicast reflector.  This constructor sends JOIN messages
        /// to the given reflector endpoint.
        ///
        /// </summary>
        /// <param name="reflectorEP"></param>
        /// <param name="multicastEP"></param>
        /// <param name="timeout"></param>
        public UdpListener(IPEndPoint multicastEP, IPEndPoint reflectorEP, int timeout)
        {
            LstSocks.Socket.SockInterfacePair sip = LstSocks.Socket.GetSharedSocket(reflectorEP);
            this.sock = sip.sock;
            this.externalInterface = sip.extInterface;
            this.nextHopEP         = reflectorEP;
            this.multicastEP       = multicastEP;

            // check whether we must "force" the local port to equal the remote port -- this is done
            // for clients behind picky firewalls.  If not, use port number 0 to indicate a "don't care"

            int port = 0;

            try
            {
                string forcePort = ConfigurationManager.AppSettings["MSR.LST.Net.ForceLocalUnicastPorts"];
                bool   force     = Boolean.Parse(forcePort);
                if (force)
                {
                    port = reflectorEP.Port;
                }
            }
            catch (Exception) { }

            lock (sip)
            {
                if (!sip.Initialized)
                {
                    try
                    {
                        InitializeSocket(port, timeout);

                        // notify the reflector of our presence...
                        joiner = new UdpReflectorJoiner(nextHopEP, multicastEP);
                        joiner.Start();

                        sip.Initialized = true;
                    }
                    catch
                    {
                        this.Dispose();
                        throw;
                    }
                }
            }
        }
Example #10
0
        internal static void ReleaseSharedSocket(IPEndPoint endPoint, LstSocks.Socket sock)
        {
            object sockObj = socks[endPoint];

            if (sockObj == null)
            {
                throw new InvalidOperationException(Strings.SockDoesNotExistAsASharedSocket);
            }

            lock (socks)
            {
                if (--sock.refCount <= 0)
                {
                    // Leave the multicast group
                    if (Utility.IsMulticast(endPoint.Address))
                    {
                        try
                        {
                            if (endPoint.AddressFamily == AddressFamily.InterNetworkV6)
                            {
                                IPv6MulticastOption mo = new IPv6MulticastOption(endPoint.Address);
                                sock.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.DropMembership, mo);
                            }
                            else
                            {
                                MulticastOption mo = new MulticastOption(endPoint.Address);
                                sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.DropMembership, mo);
                            }
                        }
                        catch {} // The user of the socket *may* not have joined the multicast group (?)
                    }

                    // Remove ourselves from the shared pool
                    socks.Remove(endPoint);

                    // Close the socket
                    try
                    {
                        sock.Close();
                    }
                    catch (ObjectDisposedException) {}
                }
            }
        }
Example #11
0
        /// <summary>
        /// This constructor is used for non-reflector sessions;
        /// if necessary, it joins the appropriate multicast group.
        /// </summary>
        /// <param name="multicastEP"></param>
        /// <param name="timeoutMilliseconds"></param>

        public UdpListener(System.Net.IPEndPoint nextHopEP, int timeoutMilliseconds)
        {
            LstSocks.Socket.SockInterfacePair sip = LstSocks.Socket.GetSharedSocket(nextHopEP);
            this.sock = sip.sock;
            this.externalInterface = sip.extInterface;
            this.nextHopEP         = nextHopEP;
            this.multicastEP       = nextHopEP;

            lock (sip)
            {
                if (!sip.Initialized)
                {
                    try
                    {
                        InitializeSocket(nextHopEP.Port, timeoutMilliseconds);

                        if (Utility.IsMulticast(nextHopEP.Address))
                        {
                            if (nextHopEP.AddressFamily == AddressFamily.InterNetworkV6)
                            {
                                // Join the IPv6 Multicast group
                                sock.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.AddMembership,
                                                     new IPv6MulticastOption(nextHopEP.Address));
                            }
                            else
                            {
                                // Join the IPv4 Multicast group
                                sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership,
                                                     new MulticastOption(nextHopEP.Address));
                            }
                        }

                        sip.Initialized = true;
                    }
                    catch
                    {
                        this.Dispose();
                        throw;
                    }
                }
            }
        }
Example #12
0
        /// <summary>
        /// Constructor that binds this object instance to an IPEndPoint.  If you need to change settings dynamically, Dispose and recreate a new object.
        /// </summary>
        /// <param name="endPoint">IPEndPoint where to send the multicast packets -- should be in range 224.0.0.0 to 239.255.255.255</param>
        /// <param name="timeToLive">ushort Time To Live of the packets -- how many routers will we cross -- set to 2 for local or testing</param>
        public UdpSender(System.Net.IPEndPoint endPoint, ushort timeToLive)
        {
            this.endPoint = endPoint;

            LstSocks.Socket.SockInterfacePair sip = LstSocks.Socket.GetSharedSocket(endPoint);
            this.sock = sip.sock;
            this.externalInterface = sip.extInterface;

            if ( Utility.IsMulticast( endPoint.Address ) )
            {
                SocketOptionLevel sOL = SocketOptionLevel.IP;
                if (endPoint.AddressFamily == AddressFamily.InterNetworkV6)
                {
                    sOL = SocketOptionLevel.IPv6;
                }
                // Set the TTL
                sock.SetSocketOption(sOL, SocketOptionName.MulticastTimeToLive, timeToLive);
                // Enable Multicast Loopback
                sock.SetSocketOption(sOL, SocketOptionName.MulticastLoopback, 1);
            }
            else
            {
                // Enable Unicast Loopback
                echoEndPoint = new IPEndPoint(externalInterface, endPoint.Port);
            }
        }
Example #13
0
 /// <summary>
 /// Dispose per the IDisposable pattern
 /// </summary>
 public void Dispose() 
 {
     GC.SuppressFinalize(this);
     
     if(!disposed) 
     {
         disposed = true;
         if (sock != null)
         {
             LstSocks.Socket.ReleaseSharedSocket(endPoint, sock);
             sock = null;
         }
     }
 }
Example #14
0
        /// <summary>
        /// Dispose per the IDisposable pattern
        /// </summary>
        public void Dispose()
        {
            GC.SuppressFinalize(this);
            
            if(!disposed) 
            {
                disposed = true;
                if (sock != null)
                {
                    // if we are using a reflector, send a tear-down message
                    if (!multicastEP.Equals(nextHopEP))
                    {
                        try
                        {
                            if (joiner != null)
                                joiner.Terminate();

                            // send a LEAVE message; this might get lost, but that doesn't matter
                            // because the reflector wil time out.
                            UdpSender sender = new UdpSender(nextHopEP, 64);
                            UdpReflectorMessage message = new UdpReflectorMessage(UdpReflectorMessageType.LEAVE, multicastEP);

                            sender.Send(message.ToBufferChunk());
                            sender.Dispose();
                        }
                        catch (Exception) { }
                    }

                    LstSocks.Socket.ReleaseSharedSocket(nextHopEP, sock);
                    sock = null;
                }
            }
        }
Example #15
0
        /// <summary>
        /// This constructor is for use with a unicast reflector.  This constructor sends JOIN messages
        /// to the given reflector endpoint.
        /// 
        /// </summary>
        /// <param name="reflectorEP"></param>
        /// <param name="multicastEP"></param>
        /// <param name="timeout"></param>
        public UdpListener(IPEndPoint multicastEP, IPEndPoint reflectorEP, int timeout)
        {
                    
            LstSocks.Socket.SockInterfacePair sip = LstSocks.Socket.GetSharedSocket(reflectorEP);
            this.sock = sip.sock;
            this.externalInterface = sip.extInterface;
            this.nextHopEP = reflectorEP;
            this.multicastEP = multicastEP;

            // check whether we must "force" the local port to equal the remote port -- this is done
            // for clients behind picky firewalls.  If not, use port number 0 to indicate a "don't care"

            int port = 0;

            try
            {
                string forcePort = ConfigurationManager.AppSettings["MSR.LST.Net.ForceLocalUnicastPorts"];
                bool force = Boolean.Parse(forcePort);
                if (force)
                    port = reflectorEP.Port;
            }
            catch (Exception) { }

            lock (sip)
            {
                if (!sip.Initialized)
                {
                    try
                    {
                        InitializeSocket(port, timeout);

                        // notify the reflector of our presence...
                        joiner = new UdpReflectorJoiner(nextHopEP, multicastEP);                        
                        joiner.Start();

                        sip.Initialized = true;
                    }
                    catch
                    {
                        this.Dispose();
                        throw;
                    }
                }
            }
        }
Example #16
0
        /// <summary>
        /// This constructor is used for non-reflector sessions; 
        /// if necessary, it joins the appropriate multicast group.
        /// </summary>
        /// <param name="multicastEP"></param>
        /// <param name="timeoutMilliseconds"></param>
    
        public UdpListener(System.Net.IPEndPoint nextHopEP, int timeoutMilliseconds)
        {
            LstSocks.Socket.SockInterfacePair sip = LstSocks.Socket.GetSharedSocket(nextHopEP);
            this.sock = sip.sock;
            this.externalInterface = sip.extInterface;
            this.nextHopEP = nextHopEP;
            this.multicastEP = nextHopEP;
            
            lock(sip)
            {
                if(!sip.Initialized)
                {
                    try
                    {
                        InitializeSocket(nextHopEP.Port, timeoutMilliseconds);

                        if(Utility.IsMulticast(nextHopEP.Address))
                        {
                            if(nextHopEP.AddressFamily == AddressFamily.InterNetworkV6)
                            {
                                // Join the IPv6 Multicast group
                                sock.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.AddMembership,
                                    new IPv6MulticastOption(nextHopEP.Address));
                            } 
                            else 
                            {
                                // Join the IPv4 Multicast group
                                sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership,
                                    new MulticastOption(nextHopEP.Address));
                            }

                        }

                        sip.Initialized = true;
                    } 
                    catch
                    {
                        this.Dispose();
                        throw;
                    }
                }
            }
        }
Example #17
0
        /// <summary>
        /// Constructor that binds this object instance to an IPEndPoint.  If you need to change IPEndPoint dynamically, Dispose and recreate a new object.
        /// </summary>
        /// <param name="endPoint">IPEndPoint where we should be listening for IP Multicast packets.</param>
        /// <param name="TimeoutMilliseconds">Milliseconds before lack of a packet == a Network Timeout</param>
        /// <example>
        /// ...
        /// MulticastUdpListener mcListener = new MulticastUdpListener(endPoint1);
        /// mcListener.Receive(packetBuffer);
        /// mcListener.Displose();
        ///
        /// MulticastUdpListener mcListener = new MulticastUdpListener(endPoint2);
        /// mcListener.Receive(packetBuffer);
        /// mcListener.Displose();
        ///
        /// mcListener = null;
        /// ...
        /// </example>
        public UdpListener(System.Net.IPEndPoint endPoint, int timeoutMilliseconds)
        {
            LstSocks.Socket.SockInterfacePair sip = LstSocks.Socket.GetSharedSocket(endPoint);
            this.sock = sip.sock;
            this.externalInterface = sip.extInterface;
            this.ep = endPoint;

            lock(sip)
            {
                if(!sip.Initialized)
                {
                    try
                    {
                        // Set the timeout on the socket
                        if( timeoutMilliseconds > 0 )
                            sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, timeoutMilliseconds);

                        // Set the socket to send & receive from this endpoint
                        sock.Bind(new IPEndPoint(externalInterface,endPoint.Port));

                        // Make room for 80 packets plus some overhead
                        sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, 1500 * 80);

                        if(Utility.IsMulticast(endPoint.Address))
                        {
                            if(endPoint.AddressFamily == AddressFamily.InterNetworkV6)
                            {
                                // Join the IPv6 Multicast group
                                sock.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.AddMembership,
                                    new IPv6MulticastOption(endPoint.Address));
                            } 
                            else 
                            {
                                // Join the IPv4 Multicast group
                                sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership,
                                    new MulticastOption(endPoint.Address));
                            }

                        }

                        sip.Initialized = true;
                    } 
                    catch
                    {
                        this.Dispose();
                        throw;
                    }
                }
            }
        }
Example #18
0
        /// <summary>
        /// Constructor that binds this object instance to an IPEndPoint.  If you need to change settings dynamically, Dispose and recreate a new object.
        /// </summary>
        /// <param name="endPoint">IPEndPoint where to send the multicast packets -- should be in range 224.0.0.0 to 239.255.255.255</param>
        /// <param name="timeToLive">ushort Time To Live of the packets -- how many routers will we cross -- set to 2 for local or testing</param>
        public UdpSender(System.Net.IPEndPoint destEndPoint, ushort timeToLive)
        {
            this.endPoint = destEndPoint;

            LstSocks.Socket.SockInterfacePair sip = LstSocks.Socket.GetSharedSocket(destEndPoint);
            this.sock = sip.sock;
            this.localRoutingInterface = sip.extInterface;

            if ( Utility.IsMulticast( destEndPoint.Address ) )
            {
                SocketOptionLevel sOL = SocketOptionLevel.IP;
                if (destEndPoint.AddressFamily == AddressFamily.InterNetworkV6)
                {
                    sOL = SocketOptionLevel.IPv6;
                }
                // Set the TTL
                sock.SetSocketOption(sOL, SocketOptionName.MulticastTimeToLive, timeToLive);
                // Enable Multicast Loopback
                sock.SetSocketOption(sOL, SocketOptionName.MulticastLoopback, 1);
            }
            else
            {
                // Enable Unicast Loopback
                /// Note: If we didn't also instantiate a UdpListener, the socket won't have been bound
                /// to a local interface.  Specifically this comes up when we use the UdpSender to transmit
                /// reports to a diagnostic server.  In this case the loopback is not needed anyway.
                IPEndPoint localEndpoint = (IPEndPoint)sock.LocalEndPoint;
                if (localEndpoint != null) {
                    echoEndPoint = new IPEndPoint(localRoutingInterface, localEndpoint.Port);
                }
            }
        }