コード例 #1
0
 internal static unsafe Error GetIPv6MulticastOption(SafeHandle socket, MulticastOption multicastOption, IPv6MulticastOption* option)
 {
     bool release = false;
     try
     {
         socket.DangerousAddRef(ref release);
         return DangerousGetIPv6MulticastOption((int)socket.DangerousGetHandle(), multicastOption, option);
     }
     finally
     {
         if (release)
         {
             socket.DangerousRelease();
         }
     }
 }
コード例 #2
0
 private static extern unsafe Error DangerousSetIPv6MulticastOption(int socket, MulticastOption multicastOption, IPv6MulticastOption* option);
コード例 #3
0
 internal static extern unsafe Error GetIPv6MulticastOption(SafeHandle socket, MulticastOption multicastOption, IPv6MulticastOption* option);
コード例 #4
0
 internal static extern unsafe Error SetIPv6MulticastOption(int socket, MulticastOption multicastOption, IPv6MulticastOption* option);
コード例 #5
0
        private void StartMulticastSocket(SocketSet info)
        {
            if (info.LocalEP.Address.IsIPv6Multicast)
            {
                try {
                    info._socket = SetupUDPSocket(AddressFamily.InterNetworkV6, ReceivePacketSize + 1);
                    info._socket.Socket.Bind(new IPEndPoint(IPAddress.IPv6Any, info.LocalEP.Port));

                    NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
                    foreach (NetworkInterface adapter in nics)
                    {
                        if (!adapter.SupportsMulticast)
                        {
                            continue;
                        }
                        if (adapter.OperationalStatus != OperationalStatus.Up)
                        {
                            continue;
                        }
                        if (adapter.Supports(NetworkInterfaceComponent.IPv6))
                        {
                            IPInterfaceProperties properties = adapter.GetIPProperties();

                            foreach (UnicastIPAddressInformation ip in properties.UnicastAddresses)
                            {
                                if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
                                {
                                    IPv6InterfaceProperties v6Ip = adapter.GetIPProperties().GetIPv6Properties();
                                    IPv6MulticastOption     mc   = new IPv6MulticastOption(info.LocalEP.Address, v6Ip.Index);
                                    try {
                                        info._socket.Socket.SetSocketOption(SocketOptionLevel.IPv6,
                                                                            SocketOptionName.AddMembership,
                                                                            mc);
                                    }
#pragma warning disable 168
                                    catch (SocketException e) {
#pragma warning restore 168
#if LOG_UDP_CHANNEL
                                        _Log.Info(
                                            m => m(
                                                $"Start Multicast:  Address {info._localEP.Address} had an exception ${e.ToString()}"));
#endif
                                    }

                                    break;
                                }
                            }
                        }
                    }
                }
#pragma warning disable 168
                catch (SocketException e) {
#pragma warning restore 168
#if LOG_UDP_CHANNEL
                    _Log.Info(
                        m => m($"Start Multicast:  Address {info._localEP.Address} had an exception ${e.ToString()}"));
                    throw;
#endif
                }
            }
            else
            {
                try {
                    info._socket = SetupUDPSocket(AddressFamily.InterNetwork, ReceivePacketSize + 1);
                    info._socket.Socket.Bind(new IPEndPoint(IPAddress.Any, info.LocalEP.Port));

                    info._socket.Socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.PacketInformation, true);

                    NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();


                    foreach (NetworkInterface adapter in nics)
                    {
                        if (!adapter.SupportsMulticast)
                        {
                            continue;
                        }
                        if (adapter.OperationalStatus != OperationalStatus.Up)
                        {
                            continue;
                        }
                        if (adapter.Supports(NetworkInterfaceComponent.IPv4))
                        {
                            IPInterfaceProperties properties = adapter.GetIPProperties();

                            foreach (UnicastIPAddressInformation ip in properties.UnicastAddresses)
                            {
                                if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                                {
                                    MulticastOption mc = new MulticastOption(info.LocalEP.Address, ip.Address);
                                    info._socket.Socket.SetSocketOption(SocketOptionLevel.IP,
                                                                        SocketOptionName.AddMembership,
                                                                        mc);
                                }
                            }
                        }
                    }
                }
#pragma warning disable 168
                catch (SocketException e) {
#pragma warning restore 168
#if LOG_UDP_CHANNEL
                    _Log.Info(m => m($"Start Multicast:  Address {info._localEP.Address} had an exception ${e.ToString()}"));
#endif
                    throw;
                }
            }


            if (ReceiveBufferSize > 0)
            {
                info._socket.Socket.ReceiveBufferSize = ReceiveBufferSize;
                if (info._socketBackup != null)
                {
                    info._socketBackup.Socket.ReceiveBufferSize = ReceiveBufferSize;
                }
            }

            if (SendBufferSize > 0)
            {
                info._socket.Socket.SendBufferSize = SendBufferSize;
                if (info._socketBackup != null)
                {
                    info._socketBackup.Socket.SendBufferSize = SendBufferSize;
                }
            }

            BeginReceive(info);
        }
コード例 #6
0
            private void DoJoin(IPEndPoint multicastAddr)
            {
                if (multicastAddr.Address.IsIPv6Multicast)
                {
                    try {
                        NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
                        foreach (NetworkInterface adapter in nics)
                        {
                            if (!adapter.SupportsMulticast)
                            {
                                continue;
                            }
                            if (adapter.OperationalStatus != OperationalStatus.Up)
                            {
                                continue;
                            }
                            if (adapter.Supports(NetworkInterfaceComponent.IPv6))
                            {
                                IPInterfaceProperties properties = adapter.GetIPProperties();

                                foreach (UnicastIPAddressInformation ip in properties.UnicastAddresses)
                                {
                                    if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
                                    {
                                        IPv6InterfaceProperties v6Ip = adapter.GetIPProperties().GetIPv6Properties();
                                        IPv6MulticastOption     mc   = new IPv6MulticastOption(multicastAddr.Address, v6Ip.Index);
                                        try {
#if LOG_UDP_CHANNEL
                                            _Log.Debug(m => m($"Join: {multicastAddr.Address} to {v6Ip.Index}"));
#endif
                                            _socket.Socket.SetSocketOption(SocketOptionLevel.IPv6,
                                                                           SocketOptionName.AddMembership,
                                                                           mc);
                                        }
#pragma warning disable 168
                                        catch (SocketException e) {
#pragma warning restore 168
#if LOG_UDP_CHANNEL
                                            _Log.Info(
                                                m => m(
                                                    $"Start Multicast:  Address {LocalEP.Address} had an exception ${e.ToString()}"));
#endif
                                        }

                                        break;
                                    }
                                }
                            }
                        }
                    }
#pragma warning disable 168
                    catch (SocketException e) {
#pragma warning restore 168
#if LOG_UDP_CHANNEL
                        _Log.Info(
                            m => m($"Start Multicast:  Address {LocalEP.Address} had an exception ${e.ToString()}"));
                        throw;
#endif
                    }
                }
                else
                {
                    try {
                        NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();

                        foreach (NetworkInterface adapter in nics)
                        {
                            if (!adapter.SupportsMulticast)
                            {
                                continue;
                            }
                            if (adapter.OperationalStatus != OperationalStatus.Up)
                            {
                                continue;
                            }
                            if (adapter.Supports(NetworkInterfaceComponent.IPv4))
                            {
                                IPInterfaceProperties properties = adapter.GetIPProperties();

                                foreach (UnicastIPAddressInformation ip in properties.UnicastAddresses)
                                {
                                    if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                                    {
                                        MulticastOption mc = new MulticastOption(multicastAddr.Address, ip.Address);
                                        if (_socketBackup != null)
                                        {
#if LOG_UDP_CHANNEL
                                            _Log.Debug(m => m($"Join: (backup) {multicastAddr.Address} to {ip.Address}"));
#endif
                                            _socketBackup.Socket.SetSocketOption(SocketOptionLevel.IP,
                                                                                 SocketOptionName.AddMembership,
                                                                                 mc);
                                        }
                                        else
                                        {
#if LOG_UDP_CHANNEL
                                            _Log.Debug(m => m($"Join:  {multicastAddr.Address} to {ip.Address}"));
#endif
                                            _socket.Socket.SetSocketOption(SocketOptionLevel.IP,
                                                                           SocketOptionName.AddMembership,
                                                                           mc);
                                        }
                                    }
                                }
                            }
                        }
                    }
#pragma warning disable 168
                    catch (SocketException e) {
#pragma warning restore 168
#if LOG_UDP_CHANNEL
                        _Log.Info(m => m($"Start Multicast:  Address {LocalEP.Address} had an exception ${e.ToString()}"));
#endif
                        throw;
                    }
                }
            }
コード例 #7
0
        // The ConnectOriginatorAndTarget method connects the
        // ClientOriginator with the ClientTarget.
        // It performs the following main tasks:
        // 1)Creates a UDP client to receive data on a specific port
        //   using IPv6 addresses.
        // 2)Joins or create a multicast group at the specified address.
        // 3)Defines the endpoint port to send data to on the ClientTarget.
        // 4)Starts the ClientTarget thread that also creates the ClientTarget object.
        // Note this method is the counterpart of the
        // ClientTarget.StartMulticastConversation().
        public static bool ConnectOriginatorAndTarget()
        {
            try
            {
// <Snippet3>

                // Bind and listen on port 2000. This constructor creates a socket
                // and binds it to the port on which to receive data. The family
                // parameter specifies that this connection uses an IPv6 address.
                clientOriginator = new UdpClient(2000, AddressFamily.InterNetworkV6);

                // Join or create a multicast group. The multicast address ranges
                // to use are specified in RFC#2375. You are free to use
                // different addresses.

                // Transform the string address into the internal format.
                m_GrpAddr = IPAddress.Parse("FF01::1");

                // Display the multicast address used.
                Console.WriteLine("Multicast Address: [" + m_GrpAddr.ToString() + "]");

// <Snippet4>
                // Exercise the use of the IPv6MulticastOption.
                Console.WriteLine("Instantiate IPv6MulticastOption(IPAddress)");

                // Instantiate IPv6MulticastOption using one of the
                // overloaded constructors.
                IPv6MulticastOption ipv6MulticastOption = new IPv6MulticastOption(m_GrpAddr);

                // Store the IPAdress multicast options.
                IPAddress group          = ipv6MulticastOption.Group;
                long      interfaceIndex = ipv6MulticastOption.InterfaceIndex;

                // Display IPv6MulticastOption properties.
                Console.WriteLine("IPv6MulticastOption.Group: [" + group + "]");
                Console.WriteLine("IPv6MulticastOption.InterfaceIndex: [" + interfaceIndex + "]");

// </Snippet4>

// <Snippet5>

                // Instantiate IPv6MulticastOption using another
                // overloaded constructor.
                IPv6MulticastOption ipv6MulticastOption2 = new IPv6MulticastOption(group, interfaceIndex);

                // Store the IPAdress multicast options.
                group          = ipv6MulticastOption2.Group;
                interfaceIndex = ipv6MulticastOption2.InterfaceIndex;

                // Display the IPv6MulticastOption2 properties.
                Console.WriteLine("IPv6MulticastOption.Group: [" + group + "]");
                Console.WriteLine("IPv6MulticastOption.InterfaceIndex: [" + interfaceIndex + "]");

                // Join the specified multicast group using one of the
                // JoinMulticastGroup overloaded methods.
                clientOriginator.JoinMulticastGroup((int)interfaceIndex, group);

// </Snippet5>

                // Define the endpoint data port. Note that this port number
                // must match the ClientTarget UDP port number which is the
                // port on which the ClientTarget is receiving data.
                m_ClientTargetdest = new IPEndPoint(m_GrpAddr, 1000);

// </Snippet3>

                // Start the ClientTarget thread so it is ready to receive.
                m_t = new Thread(new ThreadStart(ClientTarget.StartMulticastConversation));
                m_t.Start();

                // Make sure that the thread has started.
                Thread.Sleep(2000);

                return(true);
            }
            catch (Exception e)
            {
                Console.WriteLine("[ClientOriginator.ConnectClients] Exception: " + e.ToString());
                return(false);
            }
        }
コード例 #8
0
        void FindNetworkInterfaces()
        {
            var nics = GetNetworkInterfaces()
                       .Where(nic => !knownNics.Any(k => k.Id == nic.Id))
                       .ToArray();

            foreach (var nic in nics)
            {
                lock (socketLock)
                {
                    if (socket == null)
                    {
                        return;
                    }

                    IPInterfaceProperties properties = nic.GetIPProperties();
                    if (ip6)
                    {
                        var ipProperties   = properties.GetIPv6Properties();
                        var interfaceIndex = ipProperties.Index;
                        var mopt           = new IPv6MulticastOption(MulticastAddressIp6, interfaceIndex);
                        socket.SetSocketOption(
                            SocketOptionLevel.IPv6,
                            SocketOptionName.AddMembership,
                            mopt);
                        if (ipProperties.Mtu > packetOverhead)
                        {
                            // Only change maxPacketSize if Mtu is available (and it that is not the case on MacOS)
                            maxPacketSize = Math.Min(maxPacketSize, ipProperties.Mtu - packetOverhead);
                        }
                    }
                    else
                    {
                        var ipProperties   = properties.GetIPv4Properties();
                        var interfaceIndex = ipProperties.Index;
                        var mopt           = new MulticastOption(MulticastAddressIp4, interfaceIndex);
                        socket.SetSocketOption(
                            SocketOptionLevel.IP,
                            SocketOptionName.AddMembership,
                            mopt);
                        if (ipProperties.Mtu > packetOverhead)
                        {
                            // Only change maxPacketSize if Mtu is available (and it that is not the case on MacOS)
                            maxPacketSize = Math.Min(maxPacketSize, ipProperties.Mtu - packetOverhead);
                        }
                    }
                    knownNics.Add(nic);
                }
            }

            // Tell others.
            if (nics.Length > 0)
            {
                lock (socketLock)
                {
                    if (socket == null)
                    {
                        return;
                    }
                    NetworkInterfaceDiscovered?.Invoke(this, new NetworkInterfaceEventArgs
                    {
                        NetworkInterfaces = nics
                    });
                }
            }
        }
コード例 #9
0
        public void JoinASM(IPAddress groupIp, int port,
                            EMulticastInterface iface, IPAddress specificIface = null)
        {
            ValidateASM(groupIp, port);

            if (_udpClient != null)
            {
                return; // already started.
            }
            _udpClient = new UdpClient(groupIp.AddressFamily);
            Socket socket = _udpClient.Client;

            socket.SetSocketOption(
                SocketOptionLevel.Socket,
                SocketOptionName.ReuseAddress,
                true
                );

            var bindInterface = specificIface;

            if (iface != EMulticastInterface.Specific)
            {
                bindInterface = (socket.AddressFamily == AddressFamily.InterNetworkV6 ?
                                 IPAddress.IPv6Any : IPAddress.Any);
            }
            socket.Bind(new IPEndPoint(bindInterface, port));

            var joinInterfaces = new List <int>();

            if (iface == EMulticastInterface.All)
            {
                foreach (var ni in NetworkUtils.GetActiveInterfaces())
                {
                    joinInterfaces.Add(socket.AddressFamily == AddressFamily.InterNetworkV6
                        ? ni.IPv6.Index : ni.IPv4.Index);
                }
            }
            else if (iface == EMulticastInterface.Specific)
            {
                int best = NetworkUtils.GetBestMulticastInterfaceIndex(specificIface);
                if (best == -1)
                {
                    best = 0;
                }
                joinInterfaces.Add(best);
            }
            else if (iface == EMulticastInterface.Default)
            {
                joinInterfaces.Add(0); // 0 = default.
            }

            foreach (int ifaceIndex in joinInterfaces)
            {
                if (socket.AddressFamily == AddressFamily.InterNetwork)
                {
                    MulticastOption opt = new MulticastOption(
                        groupIp, ifaceIndex);

                    socket.SetSocketOption(SocketOptionLevel.IP,
                                           SocketOptionName.AddMembership, opt);
                }
                else if (socket.AddressFamily == AddressFamily.InterNetworkV6)
                {
                    IPv6MulticastOption optv6 = new IPv6MulticastOption(
                        groupIp, ifaceIndex);

                    socket.SetSocketOption(SocketOptionLevel.IPv6,
                                           SocketOptionName.AddMembership, optv6);
                }
            }

            StatusChanged?.Invoke(this,
                                  new UdpMulticastClientStatusEventArgs(true)
            {
                MulticastGroup     = new IPEndPoint(groupIp, port),
                MulticastInterface = iface,
                SpecificInterface  = specificIface
            }
                                  );

            StartReceive();
        }
コード例 #10
0
        public void Start()
        {
            if (socket_ != null)
            {
                throw new InvalidOperationException("Network is already running");
            }

            socket_ = new Socket(broadcastEndpoint_.AddressFamily, SocketType.Dgram, ProtocolType.Udp);

            // Bind to the broadcast port.
            socket_.Bind(new IPEndPoint(localAddress_, broadcastEndpoint_.Port));

            // Optionally join a multicast group
            if (IsMulticast(broadcastEndpoint_.Address))
            {
                if (broadcastEndpoint_.AddressFamily == AddressFamily.InterNetwork)
                {
                    MulticastOption mcastOption;
                    mcastOption = new MulticastOption(broadcastEndpoint_.Address, localAddress_);

                    socket_.SetSocketOption(SocketOptionLevel.IP,
                                            SocketOptionName.AddMembership,
                                            mcastOption);
                }
                else if (broadcastEndpoint_.AddressFamily == AddressFamily.InterNetworkV6)
                {
                    IPv6MulticastOption mcastOption;
                    if (localAddress_ != IPAddress.IPv6Any)
                    {
                        var ifaceIdx = GetIfaceIdxFromAddress(localAddress_);
                        mcastOption = new IPv6MulticastOption(broadcastEndpoint_.Address, ifaceIdx);
                    }
                    else
                    {
                        mcastOption = new IPv6MulticastOption(broadcastEndpoint_.Address);
                    }
                    socket_.SetSocketOption(SocketOptionLevel.IP,
                                            SocketOptionName.AddMembership,
                                            mcastOption);
                }
                else
                {
                    // Should never happen
                    throw new NotSupportedException($"Invalid address family: {broadcastEndpoint_.AddressFamily}");
                }
            }
            else
            {
                // Assume this is a broadcast address.
                socket_.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
            }

            // Start the cleanup thread.
            deleteExpiredCts_ = new CancellationTokenSource();
            var token = deleteExpiredCts_.Token;

            deleteExpiredTask_ = Task.Run(() => CleanupExpired(token), token);

            // Start the receiving thread.
            recvTask_ = Task.Run(ReceiveLoop);

            Started?.Invoke(this);
        }
コード例 #11
0
        protected override void OnOpen()
        {
            System.Diagnostics.Debug.Assert(_socket == null);
            System.Diagnostics.Debug.Assert(_remoteEp != null);
            System.Diagnostics.Debug.Assert(_localIp != null);
            System.Diagnostics.Debug.Assert(_iface != null);

            try
            {
                IPEndPoint ep = _remoteEp as IPEndPoint;

                ep.Port = Port;

                _socket = OpenSocket(ep);

                _multicast = ep.Address.IsMulticast();

                if (_multicast)
                {
                    if (Platform.GetOS() == Platform.OS.Windows)
                    {
                        // Multicast needs to bind to INADDR_ANY on windows
                        if (ep.AddressFamily == AddressFamily.InterNetwork)
                        {
                            _socket.Bind(new IPEndPoint(IPAddress.Any, SrcPort));
                        }
                        else
                        {
                            _socket.Bind(new IPEndPoint(IPAddress.IPv6Any, SrcPort));
                        }
                    }
                    else if (ep.Address.AddressFamily == AddressFamily.InterNetwork)
                    {
                        // Multicast needs to bind to the group on *nix
                        _socket.Bind(new IPEndPoint(ep.Address, SrcPort));
                    }
                    else
                    {
                        _socket.Bind(new IPEndPoint(IPAddress.IPv6Any, SrcPort));
                    }

                    SocketOptionLevel level = SocketOptionLevel.IPv6;
                    object            opt   = null;

                    if (_localIp.AddressFamily == AddressFamily.InterNetwork)
                    {
                        level = SocketOptionLevel.IP;
                        opt   = new MulticastOption(ep.Address, _localIp);
                    }
                    else if (Platform.GetOS() == Platform.OS.OSX)
                    {
                        if (_iface == null)
                        {
                            throw new PeachException("Error, could not resolve local interface name for local IP '{0}'.".Fmt(_localIp));
                        }

                        uint ifindex = if_nametoindex(_iface);

                        if (ifindex == 0)
                        {
                            throw new PeachException("Error, could not resolve interface index for interface name '{0}'.".Fmt(_iface));
                        }

                        JoinGroupV6(ep.Address, ifindex);
                    }
                    else if (_localIp != IPAddress.IPv6Any)
                    {
                        level = SocketOptionLevel.IPv6;
                        opt   = new IPv6MulticastOption(ep.Address, _localIp.ScopeId);
                    }
                    else
                    {
                        level = SocketOptionLevel.IPv6;
                        opt   = new IPv6MulticastOption(ep.Address);
                    }

                    if (opt != null)
                    {
                        _socket.SetSocketOption(level, SocketOptionName.AddMembership, opt);
                    }

                    if (_localIp != IPAddress.Any && _localIp != IPAddress.IPv6Any)
                    {
                        Logger.Trace("Setting multicast interface for {0} socket to {1}.", _type, _localIp);

                        if (level == SocketOptionLevel.IP)
                        {
                            _socket.SetSocketOption(level, SocketOptionName.MulticastInterface, _localIp.GetAddressBytes());
                        }
                        else if (Platform.GetOS() != Platform.OS.OSX)
                        {
                            _socket.SetSocketOption(level, SocketOptionName.MulticastInterface, (int)_localIp.ScopeId);
                        }
                    }
                    else if (Platform.GetOS() == Platform.OS.OSX)
                    {
                        throw new PeachException(string.Format("Error, the value for parameter 'Interface' can not be '{0}' when the 'Host' parameter is multicast.", Interface == null ? "<null>" : Interface.ToString()));
                    }
                }
                else
                {
                    _socket.Bind(new IPEndPoint(_localIp, SrcPort));
                }
            }
            catch (Exception ex)
            {
                if (_socket != null)
                {
                    _socket.Close();
                    _socket = null;
                }

                SocketException se = ex as SocketException;
                if (se != null && se.SocketErrorCode == SocketError.AccessDenied)
                {
                    throw new PeachException(string.Format("Access denied when trying open a {0} socket.  Ensure the user has the appropriate permissions.", _type), ex);
                }

                Logger.Error("Unable to open {0} socket to {1}:{2}. {3}.", _type, Host, Port, ex.Message);

                throw new SoftException(ex);
            }

            _socket.ReceiveBufferSize = MaxSendSize;
            _socket.SendBufferSize    = MaxSendSize;

            if (_recvBuffer == null || _recvBuffer.Capacity < _socket.ReceiveBufferSize)
            {
                _recvBuffer = new MemoryStream(MaxSendSize);
            }

            _localEp = _socket.LocalEndPoint;

            Logger.Trace("Opened {0} socket, Local: {1}, Remote: {2}", _type, _localEp, _remoteEp);
        }