Exemple #1
0
        static void StartMulticastAcceptor()
        {
            IPAddress localIPAddr = IPAddress.Any;
            AsyncDatagramAcceptor acceptor = new AsyncDatagramAcceptor();

            acceptor.FilterChain.AddLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Encoding.UTF8)));

            // Define a MulticastOption object specifying the multicast group  
            // address and the local IPAddress. 
            // The multicast group address is the same as the address used by the client.
            MulticastOption mcastOption = new MulticastOption(mcastAddress, localIPAddr);
            acceptor.SessionConfig.MulticastOption = mcastOption;

            acceptor.SessionOpened += (s, e) =>
            {
                Console.WriteLine("Opened: {0}", e.Session.RemoteEndPoint);
            };
            acceptor.MessageReceived += (s, e) =>
            {
                Console.WriteLine("Received from {0}: {1}", e.Session.RemoteEndPoint, e.Message);
            };

            acceptor.Bind(new IPEndPoint(localIPAddr, mcastPort));

            Console.WriteLine("Acceptor: current multicast group is: " + mcastOption.Group);
            Console.WriteLine("Acceptor: current multicast local address is: " + mcastOption.LocalAddress);
            Console.WriteLine("Waiting for multicast packets.......");
        }
Exemple #2
0
        static void StartMulticastConnector()
        {
            IPAddress localIPAddr = IPAddress.Any;
            IPEndPoint mcastEP = new IPEndPoint(mcastAddress, mcastPort);
            AsyncDatagramConnector connector = new AsyncDatagramConnector();

            connector.FilterChain.AddLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Encoding.UTF8)));

            // Set the local IP address used by the listener and the sender to 
            // exchange multicast messages. 
            connector.DefaultLocalEndPoint = new IPEndPoint(localIPAddr, 0);

            // Define a MulticastOption object specifying the multicast group  
            // address and the local IP address. 
            // The multicast group address is the same as the address used by the listener.
            MulticastOption mcastOption = new MulticastOption(mcastAddress, localIPAddr);
            connector.SessionConfig.MulticastOption = mcastOption;

            // Call Connect() to force binding to the local IP address,
            // and get the associated multicast session.
            IoSession session = connector.Connect(mcastEP).Await().Session;

            // Send multicast packets to the multicast endpoint.
            session.Write("hello 1", mcastEP);
            session.Write("hello 2", mcastEP);
            session.Write("hello 3", mcastEP);
        }
        /// <summary> 
        /// Constructor for UDP channels.
        /// </summary>
        /// <param name="localInfo"> The local endpoint to which you bind the UDP connection.
        /// <param name="remoteInfo"> A struct with the host name  and the port number 
        /// of the remote host
        /// </param>
        /// <exception cref="System.IO.IOException">  if an error occurs
        /// </exception>
        public MulticastMessageChannel(ConnectionInfo multicastInfo)
        {
            try
            {
                // Create the Socket
                udpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

                // Set the reuse address option
                udpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);

                // Create an IPEndPoint and bind to it
                IPEndPoint bindaddrs = new IPEndPoint(IPAddress.Any, multicastInfo.Port);
                udpSocket.Bind(bindaddrs);

                // Define a MulticastOption object specifying the multicast group
                // address and the local IPAddress.
                // The multicast group address is the same as the address used by the server.
                System.Net.IPAddress ipAddress = IPAddress.Parse(multicastInfo.Addr);
                MulticastOption mcastOption = new MulticastOption(ipAddress, IPAddress.Any);

                // IP multicast loopback.
                udpSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastLoopback, 1);

                // Add membership in the multicast group
                //BIG NOTE: If you have an exception at this point and your computer is disconnected
                // using Windows, the problem is due to a lack of a loopback interface.
                // You need to install a loopback interface Adapter.
                // The Microsoft Loopback adapter is a tool for testing in a
                // virtual network environment where access to a network is not feasible.
                // Click Start, point to Settings, click Control Panel, and then double-click Add/Remove Hardware.
                // You will find it in the Manufacturers section, Microsoft.
                udpSocket.SetSocketOption(SocketOptionLevel.IP,
                                        SocketOptionName.AddMembership,
                                        new MulticastOption(ipAddress, IPAddress.Any));

                // Set the Time to Live
                udpSocket.SetSocketOption(SocketOptionLevel.IP,
                                            SocketOptionName.MulticastTimeToLive, 2);

                udpMulticastAddress = new IPEndPoint(ipAddress, multicastInfo.Port);
                udpSocket.Connect(udpMulticastAddress);
            }
            catch (SocketException e)
            {
                if (log.IsErrorEnabled)
                    log.Error("SocketException caught!. Message : " + e.Message);
                throw e;
            }
            catch (Exception e)
            {
                if (log.IsErrorEnabled)
                    log.Error("Exception caught!. Message : " + e.Message);
                throw e;
            }

            if (log.IsDebugEnabled)
                log.Debug("Connected Multicast, own channel local point: " + udpSocket.LocalEndPoint
                        + " Multicast Address " + udpSocket.RemoteEndPoint);
        }
        public Task SendAsync(string data)
        {
            return Task.Factory.StartNew(() =>
            {
                IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());

                foreach(var ipAddress in localIPs.Where(a => a.AddressFamily == AddressFamily.InterNetwork))
                {
                    var mcastSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                    mcastSocket.Bind(new IPEndPoint(ipAddress, 0));
                    var mcastOption = new MulticastOption(MulticastAdress);
                    mcastSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, mcastOption);
                    var endPoint = new IPEndPoint(MulticastAdress, Port);
                    mcastSocket.SendTo(Encoding.ASCII.GetBytes(data), endPoint);
                }
            });
        }
		[Test] // .ctor (IPAddress)
		public void Constructor1 ()
		{
			MulticastOption option;
			IPAddress group;

			group = IPAddress.Parse ("239.255.255.250");
			option = new MulticastOption (group);
			Assert.AreSame (group, option.Group, "#A:Group");
			Assert.AreEqual (0, option.InterfaceIndex, "#A:InterfaceIndex");
			Assert.AreEqual (IPAddress.Any, option.LocalAddress, "#A:LocalAddress");

			group = IPAddress.Parse ("ff02::1");
			option = new MulticastOption (group);
			Assert.AreSame (group, option.Group, "#B:Group");
			Assert.AreEqual (0, option.InterfaceIndex, "#B:InterfaceIndex");
			Assert.AreEqual (IPAddress.Any, option.LocalAddress, "#B:LocalAddress");
		}
 protected virtual void CreateListeningSocket()
 {
     lock (Locker)
     {
         try
         {
             _socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
             IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, _port);
             _socket.Bind(ipEndPoint);
             IPAddress ipAddress = IPAddress.Parse(_ipAddress);
             MulticastOption multicastOption = new MulticastOption(ipAddress);
             _socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 2);
             _socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, multicastOption);
             _endPointSender = new IPEndPoint(IPAddress.Any, 0);
         }
         catch (Exception e)
         {
             Trace.Error("Socket Creation Exception", e);
         }
     }
 }
        public Task ReceiveAsync(Action<string> onData)
        {
            var cancellationToken = new CancellationToken();

            return Task.Factory.StartNew(() =>
            {
                var multicastSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                EndPoint localEndpoint = new IPEndPoint(IPAddress.Any, Port);

                multicastSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                multicastSocket.ExclusiveAddressUse = false;
                multicastSocket.Bind(localEndpoint);

                var multicastOption = new MulticastOption(MulticastAdress);

                multicastSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, multicastOption);

                var bytes = new byte[1024];
                var remoteEndpoint = (EndPoint)new IPEndPoint(IPAddress.Any, 0);

                try
                {
                    while (!cancellationToken.IsCancellationRequested)
                    {
                        int length = multicastSocket.ReceiveFrom(bytes, ref remoteEndpoint);
                        onData(Encoding.ASCII.GetString(bytes, 0, length));
                    }

                    multicastSocket.Close();
                }

                catch (Exception e)
                {
                    Console.WriteLine(e.ToString());
                }
            }, cancellationToken);
        }
Exemple #8
0
		[Test] // .ctor (IPAddress, IPAddress)
		public void Constructor2 ()
		{
			MulticastOption option;
			IPAddress group;
			IPAddress mcint;

			group = IPAddress.Parse ("239.255.255.250");
			mcint = IPAddress.Any;
			option = new MulticastOption (group, mcint);
			Assert.AreSame (group, option.Group, "#A:Group");
#if NET_2_0
			Assert.AreEqual (0, option.InterfaceIndex, "#A:InterfaceIndex");
#endif
			Assert.AreEqual (mcint, option.LocalAddress, "#A:LocalAddress");

			group = IPAddress.Parse ("ff02::1");
			mcint = IPAddress.IPv6Any;
			option = new MulticastOption (group, mcint);
			Assert.AreSame (group, option.Group, "#B:Group");
#if NET_2_0
			Assert.AreEqual (0, option.InterfaceIndex, "#B:InterfaceIndex");
#endif
			Assert.AreEqual (mcint, option.LocalAddress, "#B:LocalAddress");
		}
Exemple #9
0
        private MulticastOption getMulticastOpt(SocketOptionName optionName) {
            IPMulticastRequest ipmr = new IPMulticastRequest();
            int optlen = IPMulticastRequest.Size;

            // This can throw ObjectDisposedException.
            SocketError errorCode = UnsafeNclNativeMethods.OSSOCK.getsockopt(
                m_Handle,
                SocketOptionLevel.IP,
                optionName,
                out ipmr,
                ref optlen);

            GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::getMulticastOpt() UnsafeNclNativeMethods.OSSOCK.getsockopt returns errorCode:" + errorCode);

            //
            // if the native call fails we'll throw a SocketException
            //
            if (errorCode==SocketError.SocketError) {
                //
                // update our internal state after this socket error and throw
                //
                SocketException socketException = new SocketException();
                UpdateStatusAfterSocketError(socketException);
                if(s_LoggingEnabled)Logging.Exception(Logging.Sockets, this, "getMulticastOpt", socketException);
                throw socketException;
            }

#if BIGENDIAN
            ipmr.MulticastAddress = (int) (((uint) ipmr.MulticastAddress << 24) |
                                           (((uint) ipmr.MulticastAddress & 0x0000FF00) << 8) |
                                           (((uint) ipmr.MulticastAddress >> 8) & 0x0000FF00) |
                                           ((uint) ipmr.MulticastAddress >> 24));
            ipmr.InterfaceAddress = (int) (((uint) ipmr.InterfaceAddress << 24) |
                                           (((uint) ipmr.InterfaceAddress & 0x0000FF00) << 8) |
                                           (((uint) ipmr.InterfaceAddress >> 8) & 0x0000FF00) |
                                           ((uint) ipmr.InterfaceAddress >> 24));
#endif  // BIGENDIAN

            IPAddress multicastAddr = new IPAddress(ipmr.MulticastAddress);
            IPAddress multicastIntr = new IPAddress(ipmr.InterfaceAddress);

            MulticastOption multicastOption = new MulticastOption(multicastAddr, multicastIntr);

            return multicastOption;
        }
Exemple #10
0
        private void setMulticastOption(SocketOptionName optionName, MulticastOption MR) {
            IPMulticastRequest ipmr = new IPMulticastRequest();

            ipmr.MulticastAddress = unchecked((int)MR.Group.m_Address);


            if(MR.LocalAddress != null){
                ipmr.InterfaceAddress = unchecked((int)MR.LocalAddress.m_Address);
            }
            else {  //this structure works w/ interfaces as well
                int ifIndex =IPAddress.HostToNetworkOrder(MR.InterfaceIndex);
                ipmr.InterfaceAddress   = unchecked((int)ifIndex);
            }

#if BIGENDIAN
            ipmr.MulticastAddress = (int) (((uint) ipmr.MulticastAddress << 24) |
                                           (((uint) ipmr.MulticastAddress & 0x0000FF00) << 8) |
                                           (((uint) ipmr.MulticastAddress >> 8) & 0x0000FF00) |
                                           ((uint) ipmr.MulticastAddress >> 24));

            if(MR.LocalAddress != null){
                ipmr.InterfaceAddress = (int) (((uint) ipmr.InterfaceAddress << 24) |
                                           (((uint) ipmr.InterfaceAddress & 0x0000FF00) << 8) |
                                           (((uint) ipmr.InterfaceAddress >> 8) & 0x0000FF00) |
                                           ((uint) ipmr.InterfaceAddress >> 24));
            }
#endif  // BIGENDIAN

            GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::setMulticastOption(): optionName:" + optionName.ToString() + " MR:" + MR.ToString() + " ipmr:" + ipmr.ToString() + " IPMulticastRequest.Size:" + IPMulticastRequest.Size.ToString());

            // This can throw ObjectDisposedException.
            SocketError errorCode = UnsafeNclNativeMethods.OSSOCK.setsockopt(
                m_Handle,
                SocketOptionLevel.IP,
                optionName,
                ref ipmr,
                IPMulticastRequest.Size);

            GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::setMulticastOption() UnsafeNclNativeMethods.OSSOCK.setsockopt returns errorCode:" + errorCode);

            //
            // if the native call fails we'll throw a SocketException
            //
            if (errorCode==SocketError.SocketError) {
                //
                // update our internal state after this socket error and throw
                //
                SocketException socketException = new SocketException();
                UpdateStatusAfterSocketError(socketException);
                if(s_LoggingEnabled)Logging.Exception(Logging.Sockets, this, "setMulticastOption", socketException);
                throw socketException;
            }
        }
        private static RegisterMessage ProcessLeaveRequest(RegisterMessage leaveRequestMessage, IPAddress senderIP)
        {
            try
            {
                lock (clientRegTable.SyncRoot)
                {
                    if (clientRegTable.ContainsKey(senderIP))
                    {
                        bool drop = true;
                        clientRegTable.Remove(senderIP);
                        ReflectorMgr.PC[ReflectorPC.ID.CurrentParticipats] = clientRegTable.Count;

                        // Drop membership if no other member exists
                        foreach (ClientEntry entry in clientRegTable.Values)
                        {
                            if (entry.GroupEP.Address.Equals(leaveRequestMessage.groupIP))
                            {
                                drop = false;
                                break;
                            }
                        }

                        if (drop)
                        {
                            if (leaveRequestMessage.groupIP.AddressFamily == AddressFamily.InterNetwork)
                            {
                                MulticastOption mo = new MulticastOption(leaveRequestMessage.groupIP,ReflectorMgr.MulticastInterfaceIP);
                                ReflectorMgr.Sockets.SockMCv4RTP.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.DropMembership, mo);
                                ReflectorMgr.Sockets.SockMCv4RTCP.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.DropMembership, mo);
                            }
                            else
                            {
                                IPv6MulticastOption mo = new IPv6MulticastOption(leaveRequestMessage.groupIP);
                                ReflectorMgr.Sockets.SockMCv6RTP.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.DropMembership, mo);
                                ReflectorMgr.Sockets.SockMCv6RTCP.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.DropMembership, mo);
                            }
                        }

                        return new RegisterMessage(MessageType.Confirm, leaveRequestMessage.groupIP, leaveRequestMessage.groupPort, leaveRequestMessage.confirmNumber);
                    }
                    else
                    {   // No entries found for the leave request
                        return new RegisterMessage(MessageType.LeaveWithoutJoinError, IPAddress.Any);
                    }
                }
            }

            catch
            {
                return new RegisterMessage(MessageType.UnknownError, IPAddress.Any);
            }
        }
        private static RegisterMessage ProcessJoinRequest(RegisterMessage joinRequestMessage, IPAddress senderIP)
        {
            try
            {
                // If the senderIP already exists, remove it by following the rule - the last one wins
                if (clientRegTable.ContainsKey(senderIP))
                {
                    lock (clientRegTable.SyncRoot)
                    {
                        clientRegTable.Remove(senderIP);
                    }
                }

                // Insert the new entry
                Random rnd = new Random();
                int confirmNumber = rnd.Next(1, Int32.MaxValue);

                lock (clientRegTable.SyncRoot)
                {
                    clientRegTable.Add(senderIP, new ClientEntry(senderIP, new IPEndPoint(joinRequestMessage.groupIP,
                        joinRequestMessage.groupPort), DateTime.Now, confirmNumber, DateTime.Now));

                    ReflectorMgr.PC[ReflectorPC.ID.TotalParticipants]++;
                    ReflectorMgr.PC[ReflectorPC.ID.CurrentParticipats] = clientRegTable.Count;
                }

                joinRequestMessage.msgType = MessageType.Confirm;
                joinRequestMessage.confirmNumber = confirmNumber;
                joinRequestMessage.unicastPort = ReflectorMgr.ReflectorUnicastRTPListenPort;

                if (joinRequestMessage.groupIP.AddressFamily == AddressFamily.InterNetwork)
                {
                    MulticastOption mo = new MulticastOption(joinRequestMessage.groupIP,ReflectorMgr.MulticastInterfaceIP);
                    ReflectorMgr.Sockets.SockMCv4RTP.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, mo);
                    ReflectorMgr.Sockets.SockMCv4RTCP.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, mo);
                }
                else
                {
                    IPv6MulticastOption mo = new IPv6MulticastOption(joinRequestMessage.groupIP);
                    ReflectorMgr.Sockets.SockMCv6RTP.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.AddMembership, mo);
                    ReflectorMgr.Sockets.SockMCv6RTCP.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.AddMembership, mo);
                }
            }

            catch
            {
                joinRequestMessage.msgType = MessageType.UnknownError;
            }

            return joinRequestMessage;
        }
Exemple #13
0
        // Leaves a multicast address group.
        public void DropMulticastGroup(IPAddress multicastAddr)
        {
            // Validate input parameters.
            if (_cleanedUp)
            {
                throw new ObjectDisposedException(this.GetType().FullName);
            }
            if (multicastAddr == null)
            {
                throw new ArgumentNullException("multicastAddr");
            }

            // IPv6 Changes: we need to create the correct MulticastOption and
            //               must also check for address family compatibility.
            if (multicastAddr.AddressFamily != _family)
            {
                throw new ArgumentException(SR.Format(SR.net_protocol_invalid_multicast_family, "UDP"), "multicastAddr");
            }

            if (_family == AddressFamily.InterNetwork)
            {
                MulticastOption mcOpt = new MulticastOption(multicastAddr);

                _clientSocket.SetSocketOption(
                    SocketOptionLevel.IP,
                    SocketOptionName.DropMembership,
                    mcOpt);
            }
            else
            {
                IPv6MulticastOption mcOpt = new IPv6MulticastOption(multicastAddr);

                _clientSocket.SetSocketOption(
                    SocketOptionLevel.IPv6,
                    SocketOptionName.DropMembership,
                    mcOpt);
            }
        }
Exemple #14
0
        public void JoinMulticastGroup(IPAddress multicastAddr, IPAddress localAddress)
        {
            // Validate input parameters.
            if (_cleanedUp)
            {
                throw new ObjectDisposedException(this.GetType().FullName);
            }

            if (_family != AddressFamily.InterNetwork)
            {
                throw new SocketException((int)SocketError.OperationNotSupported);
            }

            MulticastOption mcOpt = new MulticastOption(multicastAddr, localAddress);

            _clientSocket.SetSocketOption(
               SocketOptionLevel.IP,
               SocketOptionName.AddMembership,
               mcOpt);
        }
Exemple #15
0
        public static SocketError GetMulticastOption(SafeCloseSocket handle, SocketOptionName optionName, out MulticastOption optionValue)
        {
            Interop.Winsock.IPMulticastRequest ipmr = new Interop.Winsock.IPMulticastRequest();
            int optlen = Interop.Winsock.IPMulticastRequest.Size;

            // This can throw ObjectDisposedException.
            SocketError errorCode = Interop.Winsock.getsockopt(
                handle,
                SocketOptionLevel.IP,
                optionName,
                out ipmr,
                ref optlen);

            if (errorCode == SocketError.SocketError)
            {
                optionValue = default(MulticastOption);
                return(GetLastSocketError());
            }

#if BIGENDIAN
            ipmr.MulticastAddress = (int)(((uint)ipmr.MulticastAddress << 24) |
                                          (((uint)ipmr.MulticastAddress & 0x0000FF00) << 8) |
                                          (((uint)ipmr.MulticastAddress >> 8) & 0x0000FF00) |
                                          ((uint)ipmr.MulticastAddress >> 24));
            ipmr.InterfaceAddress = (int)(((uint)ipmr.InterfaceAddress << 24) |
                                          (((uint)ipmr.InterfaceAddress & 0x0000FF00) << 8) |
                                          (((uint)ipmr.InterfaceAddress >> 8) & 0x0000FF00) |
                                          ((uint)ipmr.InterfaceAddress >> 24));
#endif  // BIGENDIAN

            IPAddress multicastAddr = new IPAddress(ipmr.MulticastAddress);
            IPAddress multicastIntr = new IPAddress(ipmr.InterfaceAddress);
            optionValue = new MulticastOption(multicastAddr, multicastIntr);

            return(SocketError.Success);
        }
Exemple #16
0
		[Test] // SetSocketOption (SocketOptionLevel, SocketOptionName, Object)
		public void SetSocketOption3_DropMembershipIPv4_MulticastOption ()
		{
			IPAddress mcast_addr = IPAddress.Parse ("239.255.255.250");

			using (Socket s = new Socket (AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) {
				MulticastOption option = new MulticastOption (mcast_addr);

				s.Bind (new IPEndPoint (IPAddress.Any, 1901));
				s.SetSocketOption (SocketOptionLevel.IP, SocketOptionName.AddMembership,
					option);
				s.SetSocketOption (SocketOptionLevel.IP, SocketOptionName.DropMembership,
					option);
			}
		}
Exemple #17
0
        public static unsafe SocketError SetMulticastOption(SafeCloseSocket handle, SocketOptionName optionName, MulticastOption optionValue)
        {
            Debug.Assert(optionName == SocketOptionName.AddMembership || optionName == SocketOptionName.DropMembership);

            Interop.Sys.MulticastOption optName = optionName == SocketOptionName.AddMembership ?
                Interop.Sys.MulticastOption.MULTICAST_ADD :
                Interop.Sys.MulticastOption.MULTICAST_DROP;

            var opt = new Interop.Sys.IPv4MulticastOption {
                MulticastAddress = unchecked((uint)optionValue.Group.GetAddress()),
                LocalAddress = unchecked((uint)optionValue.LocalAddress.GetAddress()),
                InterfaceIndex = optionValue.InterfaceIndex
            };

            Interop.Error err = Interop.Sys.SetIPv4MulticastOption(handle.FileDescriptor, optName, &opt);
            return err == Interop.Error.SUCCESS ? SocketError.Success : GetSocketErrorForErrorCode(err);
        }
Exemple #18
0
        //internal class SockInterfacePair
        //{
        //    internal UdpSocket sock;
        //    internal IPAddress extInterface;
        //    public bool Initialized;

        //    internal SockInterfacePair(UdpSocket sock, IPAddress extIntf)
        //    {
        //        this.sock = sock;
        //        this.extInterface = extIntf;
        //        Initialized = false;
        //    }
        //}


        // 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
        //            UdpSocket sock = new UdpSocket(endPoint.AddressFamily);

        //            // 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(sock, externalInterface);
        //            socks.Add(endPoint, sip);

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

        //            return sip;
        //        }
        //    }
        //}

        //internal static void ReleaseSharedSocket(IPEndPoint endPoint, UdpSocket 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) { }
        //        }
        //    }
        //}

        internal static void ReleaseSocket(IPEndPoint endPoint, UdpSocket sock)
        {
            // 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 (?)
            }

            // Close the socket
            try
            {
                sock.Close();
            }
            catch (ObjectDisposedException) { }
        }
		[Test] // .ctor (IPAddress, Int32)
		public void Constructor3 ()
		{
			MulticastOption option;
			IPAddress group;
			int interfaceIndex;

			group = IPAddress.Parse ("239.255.255.250");
			interfaceIndex = 0;
			option = new MulticastOption (group, interfaceIndex);
			Assert.AreSame (group, option.Group, "#A:Group");
			Assert.AreEqual (interfaceIndex, option.InterfaceIndex, "#A:InterfaceIndex");
			Assert.AreEqual (null, option.LocalAddress, "#A:LocalAddress");

			group = IPAddress.Parse ("ff02::1");
			interfaceIndex = 0;
			option = new MulticastOption (group, interfaceIndex);
			Assert.AreSame (group, option.Group, "#B:Group");
			Assert.AreEqual (interfaceIndex, option.InterfaceIndex, "#B:InterfaceIndex");
			Assert.AreEqual (null, option.LocalAddress, "#B:LocalAddress");

			group = IPAddress.Parse ("239.255.255.250");
			interfaceIndex = 124;
			option = new MulticastOption (group, interfaceIndex);
			Assert.AreSame (group, option.Group, "#C:Group");
			Assert.AreEqual (interfaceIndex, option.InterfaceIndex, "#C:InterfaceIndex");
			Assert.AreEqual (null, option.LocalAddress, "#C:LocalAddress");

			group = IPAddress.Parse ("ff02::1");
			interfaceIndex = 124;
			option = new MulticastOption (group, interfaceIndex);
			Assert.AreSame (group, option.Group, "#D:Group");
			Assert.AreEqual (interfaceIndex, option.InterfaceIndex, "#D:InterfaceIndex");
			Assert.AreEqual (null, option.LocalAddress, "#D:LocalAddress");

			group = IPAddress.Parse ("239.255.255.250");
			interfaceIndex = 0xFFFFFF;
			option = new MulticastOption (group, interfaceIndex);
			Assert.AreSame (group, option.Group, "#E:Group");
			Assert.AreEqual (interfaceIndex, option.InterfaceIndex, "#E:InterfaceIndex");
			Assert.AreEqual (null, option.LocalAddress, "#E:LocalAddress");

			group = IPAddress.Parse ("ff02::1");
			interfaceIndex = 0xFFFFFF;
			option = new MulticastOption (group, interfaceIndex);
			Assert.AreSame (group, option.Group, "#F:Group");
			Assert.AreEqual (interfaceIndex, option.InterfaceIndex, "#F:InterfaceIndex");
			Assert.AreEqual (null, option.LocalAddress, "#F:LocalAddress");
		}
 public void JoinMulticastGroup(IPAddress multicastAddr, IPAddress localAddress)
 {
     if (this.m_CleanedUp)
     {
         throw new ObjectDisposedException(base.GetType().FullName);
     }
     if (this.m_Family != AddressFamily.InterNetwork)
     {
         throw new SocketException(SocketError.OperationNotSupported);
     }
     MulticastOption optionValue = new MulticastOption(multicastAddr, localAddress);
     this.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, optionValue);
 }
 public void JoinMulticastGroup(IPAddress multicastAddr)
 {
     if (this.m_CleanedUp)
     {
         throw new ObjectDisposedException(base.GetType().FullName);
     }
     if (multicastAddr == null)
     {
         throw new ArgumentNullException("multicastAddr");
     }
     if (multicastAddr.AddressFamily != this.m_Family)
     {
         throw new ArgumentException(SR.GetString("net_protocol_invalid_multicast_family", new object[] { "UDP" }), "multicastAddr");
     }
     if (this.m_Family == AddressFamily.InterNetwork)
     {
         MulticastOption optionValue = new MulticastOption(multicastAddr);
         this.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, optionValue);
     }
     else
     {
         IPv6MulticastOption option2 = new IPv6MulticastOption(multicastAddr);
         this.Client.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.AddMembership, option2);
     }
 }
Exemple #22
0
        public static unsafe SocketError SetMulticastOption(SafeCloseSocket handle, SocketOptionName optionName, MulticastOption optionValue)
        {
            int optLevel, optName;
            GetPlatformOptionInfo(SocketOptionLevel.IP, optionName, out optLevel, out optName);

            var mreqn = new Interop.libc.ip_mreqn {
                imr_multiaddr = new Interop.libc.in_addr {
                    s_addr = unchecked((uint)optionValue.Group.GetAddress())
                }
            };
            if (optionValue.LocalAddress != null)
            {
                mreqn.imr_address.s_addr = unchecked((uint)optionValue.LocalAddress.GetAddress());
            }
            else
            {
                // TODO: what is the endianness of ipv6mr_ifindex?
                mreqn.imr_ifindex = optionValue.InterfaceIndex;
            }

            int err = Interop.libc.setsockopt(handle.FileDescriptor, optLevel, optName, &mreqn, (uint)sizeof(Interop.libc.ip_mreqn));
            return err == -1 ? GetLastSocketError() : SocketError.Success;
        }
Exemple #23
0
        public static SocketError SetMulticastOption(SafeCloseSocket handle, SocketOptionName optionName, MulticastOption optionValue)
        {
            Interop.Winsock.IPMulticastRequest ipmr = new Interop.Winsock.IPMulticastRequest();

            ipmr.MulticastAddress = unchecked ((int)optionValue.Group.GetAddress());

            if (optionValue.LocalAddress != null)
            {
                ipmr.InterfaceAddress = unchecked ((int)optionValue.LocalAddress.GetAddress());
            }
            else
            {  //this structure works w/ interfaces as well
                int ifIndex = IPAddress.HostToNetworkOrder(optionValue.InterfaceIndex);
                ipmr.InterfaceAddress = unchecked ((int)ifIndex);
            }

#if BIGENDIAN
            ipmr.MulticastAddress = (int)(((uint)ipmr.MulticastAddress << 24) |
                                          (((uint)ipmr.MulticastAddress & 0x0000FF00) << 8) |
                                          (((uint)ipmr.MulticastAddress >> 8) & 0x0000FF00) |
                                          ((uint)ipmr.MulticastAddress >> 24));

            if (optionValue.LocalAddress != null)
            {
                ipmr.InterfaceAddress = (int)(((uint)ipmr.InterfaceAddress << 24) |
                                              (((uint)ipmr.InterfaceAddress & 0x0000FF00) << 8) |
                                              (((uint)ipmr.InterfaceAddress >> 8) & 0x0000FF00) |
                                              ((uint)ipmr.InterfaceAddress >> 24));
            }
#endif

            // This can throw ObjectDisposedException.
            SocketError errorCode = Interop.Winsock.setsockopt(
                handle,
                SocketOptionLevel.IP,
                optionName,
                ref ipmr,
                Interop.Winsock.IPMulticastRequest.Size);
            return(errorCode == SocketError.SocketError ? GetLastSocketError() : SocketError.Success);
        }
Exemple #24
0
        public static unsafe SocketError GetMulticastOption(SafeCloseSocket handle, SocketOptionName optionName, out MulticastOption optionValue)
        {
            int optLevel, optName;
            GetPlatformOptionInfo(SocketOptionLevel.IP, optionName, out optLevel, out optName);

            var mreqn = new Interop.libc.ip_mreqn();
            var optLen = (uint)sizeof(Interop.libc.ip_mreqn);
            int err = Interop.libc.getsockopt(handle.FileDescriptor, optLevel, optName, &mreqn, &optLen);
            if (err == -1)
            {
                optionValue = default(MulticastOption);
                return GetLastSocketError();
            }

            var multicastAddress = new IPAddress((long)mreqn.imr_multiaddr.s_addr);
            var multicastInterface = new IPAddress((long)mreqn.imr_address.s_addr);
            optionValue = new MulticastOption(multicastAddress, multicastInterface);
            return SocketError.Success;
        }
        async Task NetworkRequestAsync(byte[] requestBytes,
                                              TimeSpan scanTime,
                                              int retries,
                                              int retryDelayMilliseconds,
                                              Action<string, byte[]> onResponse,
                                              System.Net.NetworkInformation.NetworkInterface adapter,
                                              CancellationToken cancellationToken)
        {
            // http://stackoverflow.com/questions/2192548/specifying-what-network-interface-an-udp-multicast-should-go-to-in-net

#if !XAMARIN
            if (!adapter.GetIPProperties().MulticastAddresses.Any())
                return; // most of VPN adapters will be skipped
#endif
            if (!adapter.SupportsMulticast)
                return; // multicast is meaningless for this type of connection

            if (OperationalStatus.Up != adapter.OperationalStatus)
                return; // this adapter is off or not connected

            if (adapter.NetworkInterfaceType == NetworkInterfaceType.Loopback)
                return; // strip out loopback addresses

            var p = adapter.GetIPProperties().GetIPv4Properties();
            if (null == p)
                return; // IPv4 is not configured on this adapter

            var ipv4Address = adapter.GetIPProperties().UnicastAddresses
                                    .FirstOrDefault(ua => ua.Address.AddressFamily == AddressFamily.InterNetwork)?.Address;

            if (ipv4Address == null)
                return; // could not find an IPv4 address for this adapter

            var ifaceIndex = p.Index;

            Debug.WriteLine($"Scanning on iface {adapter.Name}, idx {ifaceIndex}, IP: {ipv4Address}");

            using (var client = new UdpClient())
            {
                for (var i = 0; i < retries; i++)
                {
#if ANDROID
                    var mlock = wifi.CreateMulticastLock("Zeroconf lock");
#endif
                    try
                    {
#if ANDROID
                        mlock.Acquire();
#endif
                        client.Client.SetSocketOption(SocketOptionLevel.IP,
                                                      SocketOptionName.MulticastInterface,
                                                      IPAddress.HostToNetworkOrder(ifaceIndex));



                        client.ExclusiveAddressUse = false;
                        client.Client.SetSocketOption(SocketOptionLevel.Socket,
                                                      SocketOptionName.ReuseAddress,
                                                      true);
                        client.Client.SetSocketOption(SocketOptionLevel.Socket,
                                                      SocketOptionName.ReceiveTimeout,
                                                      scanTime.Milliseconds);
                        client.ExclusiveAddressUse = false;

                        
                        var localEp = new IPEndPoint(IPAddress.Any, 5353);

                        Debug.WriteLine($"Attempting to bind to {localEp} on adapter {adapter.Name}");
                        client.Client.Bind(localEp);
                        Debug.WriteLine($"Bound to {localEp}");

                        var multicastAddress = IPAddress.Parse("224.0.0.251");
                        var multOpt = new MulticastOption(multicastAddress, ifaceIndex);
                        client.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, multOpt);


                        Debug.WriteLine("Bound to multicast address");

                        // Start a receive loop
                        var shouldCancel = false;
                        var recTask = Task.Run(async
                                               () =>
                                               {
                                                   try
                                                   {
                                                       while (!shouldCancel)
                                                       {
                                                           var res = await client.ReceiveAsync()
                                                                                 .ConfigureAwait(false);
                                                           onResponse(res.RemoteEndPoint.Address.ToString(), res.Buffer);
                                                       }
                                                   }
                                                   catch (ObjectDisposedException)
                                                   {
                                                   }
                                               }, cancellationToken);

                        var broadcastEp = new IPEndPoint(IPAddress.Parse("224.0.0.251"), 5353);
                        Debug.WriteLine($"About to send on iface {adapter.Name}");
                        await client.SendAsync(requestBytes, requestBytes.Length, broadcastEp)
                                    .ConfigureAwait(false);
                        Debug.WriteLine($"Sent mDNS query on iface {adapter.Name}");


                        // wait for responses
                        await Task.Delay(scanTime, cancellationToken)
                                  .ConfigureAwait(false);
                        shouldCancel = true;
#if CORECLR
                        client.Dispose();
#else
                        client.Close();
#endif

                        Debug.WriteLine("Done Scanning");


                        await recTask.ConfigureAwait(false);

                        return;
                    }
                    catch (Exception e)
                    {
                        Debug.WriteLine($"Execption with network request, IP {ipv4Address}\n: {e}");
                        if (i + 1 >= retries) // last one, pass underlying out
                            throw;
                    }
                    finally
                    {
#if ANDROID
                        mlock.Release();
#endif
                    }

                    await Task.Delay(retryDelayMilliseconds, cancellationToken).ConfigureAwait(false);
                }
            }
        }
Exemple #26
0
        public static unsafe SocketError GetMulticastOption(SafeCloseSocket handle, SocketOptionName optionName, out MulticastOption optionValue)
        {
            Debug.Assert(optionName == SocketOptionName.AddMembership || optionName == SocketOptionName.DropMembership);

            Interop.Sys.MulticastOption optName = optionName == SocketOptionName.AddMembership ?
                Interop.Sys.MulticastOption.MULTICAST_ADD :
                Interop.Sys.MulticastOption.MULTICAST_DROP;

            Interop.Sys.IPv4MulticastOption opt;
            Interop.Error err = Interop.Sys.GetIPv4MulticastOption(handle.FileDescriptor, optName, &opt);
            if (err != Interop.Error.SUCCESS)
            {
                optionValue = default(MulticastOption);
                return GetSocketErrorForErrorCode(err);
            }

            var multicastAddress = new IPAddress((long)opt.MulticastAddress);
            var localAddress = new IPAddress((long)opt.LocalAddress);
            optionValue = new MulticastOption(multicastAddress, localAddress) {
                InterfaceIndex = opt.InterfaceIndex
            };

            return SocketError.Success;
        }
		public void Group ()
		{
			IPAddress group;
			IPAddress local;
			MulticastOption option;

			local = Dns.GetHostEntry (string.Empty).AddressList [0];
			group = IPAddress.Parse ("239.255.255.250");
			option = new MulticastOption (group, local);
			group = IPAddress.Parse ("224.0.0.23");
			option.Group = group;
			Assert.AreSame (group, option.Group, "#A1");
			Assert.AreSame (local, option.LocalAddress, "#A2");
			group = IPAddress.Parse ("239.255.255.250");
			option.Group = group;
			Assert.AreSame (group, option.Group, "#B1");
			Assert.AreSame (local, option.LocalAddress, "#B2");
			group = IPAddress.Parse ("ff02::1");
			option.Group = group;
			Assert.AreSame (group, option.Group, "#C1");
			Assert.AreSame (local, option.LocalAddress, "#C2");
			option.Group = null;
			Assert.IsNull (option.Group, "#D1");
			Assert.AreSame (local, option.LocalAddress, "#D2");
			option = new MulticastOption (group, 5);
			group = IPAddress.Parse ("224.0.0.23");
			option.Group = group;
			Assert.AreSame (group, option.Group, "#E1");
			Assert.AreEqual (5, option.InterfaceIndex, "#E2");
			Assert.IsNull (option.LocalAddress, "#E3");
		}
Exemple #28
0
        private void SetMulticastOption(SocketOptionName optionName, MulticastOption MR)
        {
            SocketError errorCode = SocketPal.SetMulticastOption(_handle, optionName, MR);

            GlobalLog.Print("Socket#" + Logging.HashString(this) + "::setMulticastOption() Interop.Winsock.setsockopt returns errorCode:" + errorCode);

            // Throw an appropriate SocketException if the native call fails.
            if (errorCode != SocketError.Success)
            {
                // Update the internal state of this socket according to the error before throwing.
                SocketException socketException = new SocketException((int)errorCode);
                UpdateStatusAfterSocketError(socketException);
                if (s_loggingEnabled)
                {
                    Logging.Exception(Logging.Sockets, this, "setMulticastOption", socketException);
                }
                throw socketException;
            }
        }
		public void InterfaceIndex ()
		{
			IPAddress group;
			IPAddress local;
			MulticastOption option;
		
			group = IPAddress.Parse ("239.255.255.250");
			option = new MulticastOption (group, 10);
			option.InterfaceIndex = 0;
			Assert.AreSame (group, option.Group, "#A1");
			Assert.AreEqual (0, option.InterfaceIndex, "#A2");
			Assert.IsNull (option.LocalAddress, "#A3");
			option.InterfaceIndex = 124;
			Assert.AreSame (group, option.Group, "#B1");
			Assert.AreEqual (124, option.InterfaceIndex, "#B2");
			Assert.IsNull (option.LocalAddress, "#B3");
			option.InterfaceIndex = 0xFFFFFF;
			Assert.AreSame (group, option.Group, "#C1");
			Assert.AreEqual (0xFFFFFF, option.InterfaceIndex, "#C2");
			Assert.IsNull (option.LocalAddress, "#C3");

			local = Dns.GetHostEntry (string.Empty).AddressList [0];
			option = new MulticastOption (group, local);
			option.InterfaceIndex = 10;
			Assert.AreSame (group, option.Group, "#D1");
			Assert.AreEqual (10, option.InterfaceIndex, "#D2");
			Assert.IsNull (option.LocalAddress, "#D3");
		}
		public void InterfaceIndex_Value_OutOfRange ()
		{
			IPAddress group = IPAddress.Parse ("239.255.255.250");
			MulticastOption option = new MulticastOption (group, 10);

			try {
				option.InterfaceIndex = -1;
				Assert.Fail ("#A1");
			} catch (ArgumentOutOfRangeException ex) {
				// Specified argument was out of the range of valid values
				Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#A2");
				Assert.IsNull (ex.InnerException, "#A3");
				Assert.IsNotNull (ex.Message, "#A4");
				Assert.AreEqual ("value", ex.ParamName, "#A5");
			}

			try {
				option.InterfaceIndex = 0x1000000;
				Assert.Fail ("#B1");
			} catch (ArgumentOutOfRangeException ex) {
				// Specified argument was out of the range of valid values
				Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#B2");
				Assert.IsNull (ex.InnerException, "#B3");
				Assert.IsNotNull (ex.Message, "#B4");
				Assert.AreEqual ("value", ex.ParamName, "#B5");
			}

			// ensure original value was retained
			Assert.AreEqual (10, option.InterfaceIndex, "#C");
		}
		public void LocalAddress ()
		{
			IPAddress group;
			IPAddress local;
			MulticastOption option;

			local = Dns.GetHostEntry (string.Empty).AddressList [0];
			group = IPAddress.Parse ("239.255.255.250");
			option = new MulticastOption (group, local);
			local = IPAddress.Loopback;
			option.LocalAddress = local;
			Assert.AreSame (group, option.Group, "#A1");
			Assert.AreEqual (0, option.InterfaceIndex, "#A2");
			Assert.AreSame (local, option.LocalAddress, "#A3");
			local = Dns.GetHostEntry (string.Empty).AddressList [0];
			option.LocalAddress = local;
			Assert.AreSame (group, option.Group, "#B1");
			Assert.AreEqual (0, option.InterfaceIndex, "#B2");
			Assert.AreSame (local, option.LocalAddress, "#B3");
			option.LocalAddress = null;
			Assert.AreSame (group, option.Group, "#C1");
			Assert.AreEqual (0, option.InterfaceIndex, "#C2");
			Assert.IsNull (option.LocalAddress, "#C3");
			option = new MulticastOption (group, 5);
			local = IPAddress.Loopback;
			option.LocalAddress = local;
			Assert.AreSame (group, option.Group, "#D1");
			Assert.AreEqual (0, option.InterfaceIndex, "#D2");
			Assert.AreSame (local, option.LocalAddress, "#D3");
		}
Exemple #32
0
        internal static void ReleaseSharedSocket(IPEndPoint endPoint, LstSocks.Socket sock)
        {
            object sockObj = socks[endPoint];
            if( sockObj == null )
                throw new InvalidOperationException("Sock does not exist as a shared socket.");

            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) {}
                }
            }
        }
        public static SocketError SetMulticastOption(SafeSocketHandle handle, SocketOptionName optionName, MulticastOption optionValue)
        {
            Interop.Winsock.IPMulticastRequest ipmr = default;

#pragma warning disable CS0618 // Address is marked obsolete
            ipmr.MulticastAddress = unchecked ((int)optionValue.Group.Address);
#pragma warning restore CS0618

            if (optionValue.LocalAddress != null)
            {
#pragma warning disable CS0618 // Address is marked obsolete
                ipmr.InterfaceAddress = unchecked ((int)optionValue.LocalAddress.Address);
#pragma warning restore CS0618
            }
            else
            {  //this structure works w/ interfaces as well
                int ifIndex = IPAddress.HostToNetworkOrder(optionValue.InterfaceIndex);
                ipmr.InterfaceAddress = unchecked ((int)ifIndex);
            }

#if BIGENDIAN
            ipmr.MulticastAddress = BinaryPrimitives.ReverseEndianness(ipmr.MulticastAddress);

            if (optionValue.LocalAddress != null)
            {
                ipmr.InterfaceAddress = BinaryPrimitives.ReverseEndianness(ipmr.InterfaceAddress);
            }
#endif

            // This can throw ObjectDisposedException.
            SocketError errorCode = Interop.Winsock.setsockopt(
                handle,
                SocketOptionLevel.IP,
                optionName,
                ref ipmr,
                Interop.Winsock.IPMulticastRequest.Size);
            return(errorCode == SocketError.SocketError ? GetLastSocketError() : SocketError.Success);
        }