Exemple #1
0
 private void Callback(IAsyncResult result)
 {
     try
     {
         UdpBroadcastMessage message = null;
         IPEndPoint          ep      = mBroadcastEp;
         using (MemoryStream ms = new MemoryStream(mUdpClient.EndReceive(result, ref ep)))
         {
             ms.Position = 0;
             message     = mMessageFormatter.Read(ms);
             ms.SetLength(0);
         }
         if (LOGGER.IsInfoEnabled)
         {
             LOGGER.Info(string.Format("BROADCAST_SERVER, a broadcast message arrived from '{0}'.", message.SenderId));
         }
         if (NetworkManager.Instance.InternalLocalhost.Id.Equals(message.SenderId))
         {
             if (LOGGER.IsInfoEnabled)
             {
                 LOGGER.Info("BROADCAST_SERVER, this broadcast message arrived from me.");
             }
         }
         else
         {
             if (NetworkManager.Instance.NetworkContextRuleManager.CheckSeparation(NetworkManager.Instance.InternalLocalhost.NetworkContext.Name,
                                                                                   message.NetworkContextName))
             {
                 // láthatom ezt a context-et, megpróbálok rácsatlakozni
                 INetworkPeerRemote peer = NetworkPeerContext.GetNetworkPeerById(message.SenderId);
                 if (peer == null || (peer != null && peer.Distance != 1))
                 {
                     // nincs közvetlen kapcsolatom ilyen peer-el
                     mThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(ConnectionTask), message);
                 }
                 else
                 {
                     if (LOGGER.IsInfoEnabled)
                     {
                         LOGGER.Info(string.Format("BROADCAST_SERVER, this is a known peer with direct network connection. No need to establish a new. PeerId: '{0}'.", peer.Id));
                     }
                 }
             }
             else
             {
                 if (LOGGER.IsInfoEnabled)
                 {
                     LOGGER.Info(string.Format("BROADCAST_SERVER, network context separation is active between '{0}' and '{1}'.", NetworkManager.Instance.InternalLocalhost.NetworkContext.Name, message.NetworkContextName));
                 }
             }
         }
     }
     catch (Exception ex)
     {
         if (LOGGER.IsErrorEnabled)
         {
             LOGGER.Error(string.Format("BROADCAST_SERVER, failed to receive a broadcast message. Reason: {0}", ex.Message));
         }
     }
     finally
     {
         BeginReceive();
     }
 }
Exemple #2
0
        internal void InitializeUDPDetector()
        {
            if (NetworkManager.Instance.InternalConfiguration.NetworkPeering.UDPDetection.Enabled)
            {
                {
                    // UDP szerver indítása
                    List <int> listeningPorts = NetworkManager.Instance.InternalConfiguration.NetworkPeering.UDPDetection.BroadcastListeningPorts;
                    if (listeningPorts.Count > 0)
                    {
                        if (NetworkManager.Instance.InternalConfiguration.NetworkPeering.UDPDetection.DetectionMode == UDPDetectionModeEnum.Multicast)
                        {
                            Action <AddressFamily, string> initMulticastUdpClient = ((a, ip) =>
                            {
                                IPEndPoint broadcastEp = null;
                                System.Net.Sockets.UdpClient udpClient = null;
                                foreach (int port in listeningPorts)
                                {
                                    try
                                    {
                                        if (LOGGER.IsInfoEnabled)
                                        {
                                            LOGGER.Info(string.Format("CONNECTION_MANAGER, trying to initialize broadcast detector on port {0} ({1}).", port, a.ToString()));
                                        }
                                        IPAddress multicastAddress = IPAddress.Parse(ip); // (239.0.0.222)
                                        broadcastEp = new IPEndPoint(a == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any, port);
                                        udpClient = new System.Net.Sockets.UdpClient(a);

                                        udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                                        udpClient.ExclusiveAddressUse = false;
                                        udpClient.Client.Bind(broadcastEp);
                                        udpClient.EnableBroadcast = true;
                                        udpClient.MulticastLoopback = true;
                                        udpClient.AllowNatTraversal(true);

                                        udpClient.JoinMulticastGroup(multicastAddress);

                                        if (LOGGER.IsInfoEnabled)
                                        {
                                            LOGGER.Info(string.Format("CONNECTION_MANAGER, broadcast detector initialized on port {0} ({1}).", port, a.ToString()));
                                        }
                                        break;
                                    }
                                    catch (Exception ex)
                                    {
                                        if (LOGGER.IsErrorEnabled)
                                        {
                                            LOGGER.Error(string.Format("CONNECTION_MANAGER, failed to initialize broadcast detector on port {0} ({1}). Reason: {2}", port, a.ToString(), ex.Message), ex);
                                        }
                                    }
                                }
                                if (udpClient != null)
                                {
                                    BroadcastServer server = new BroadcastServer(broadcastEp, udpClient);
                                    mBroadcastServers.Add(server);
                                    server.BeginReceive();
                                }
                            });
                            if (!string.IsNullOrEmpty(NetworkManager.Instance.InternalConfiguration.NetworkPeering.UDPDetection.IPv4MulticastAddress))
                            {
                                initMulticastUdpClient(AddressFamily.InterNetwork, NetworkManager.Instance.InternalConfiguration.NetworkPeering.UDPDetection.IPv4MulticastAddress);
                            }
                            if (NetworkManager.Instance.InternalConfiguration.Settings.EnableIPV6 && !string.IsNullOrEmpty(NetworkManager.Instance.InternalConfiguration.NetworkPeering.UDPDetection.IPv6MulticastAddress))
                            {
                                initMulticastUdpClient(AddressFamily.InterNetworkV6, NetworkManager.Instance.InternalConfiguration.NetworkPeering.UDPDetection.IPv6MulticastAddress);
                            }
                        }

                        if (NetworkManager.Instance.InternalConfiguration.NetworkPeering.UDPDetection.DetectionMode == UDPDetectionModeEnum.Broadcast)
                        {
                            Action <AddressFamily> initUdpClient = (a =>
                            {
                                IPEndPoint broadcastEp = null;
                                System.Net.Sockets.UdpClient udpClient = null;
                                foreach (int port in listeningPorts)
                                {
                                    try
                                    {
                                        if (LOGGER.IsInfoEnabled)
                                        {
                                            LOGGER.Info(string.Format("CONNECTION_MANAGER, trying to initialize broadcast detector on port {0} ({1}).", port, a.ToString()));
                                        }
                                        broadcastEp = new IPEndPoint(a == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any, port);
                                        udpClient = new System.Net.Sockets.UdpClient(broadcastEp);
                                        udpClient.EnableBroadcast = true;
                                        udpClient.AllowNatTraversal(true);
                                        if (a == AddressFamily.InterNetwork)
                                        {
                                            udpClient.DontFragment = true;
                                        }
                                        if (LOGGER.IsInfoEnabled)
                                        {
                                            LOGGER.Info(string.Format("CONNECTION_MANAGER, broadcast detector initialized on port {0} ({1}).", port, a.ToString()));
                                        }
                                        break;
                                    }
                                    catch (Exception ex)
                                    {
                                        if (LOGGER.IsErrorEnabled)
                                        {
                                            LOGGER.Error(string.Format("CONNECTION_MANAGER, failed to initialize broadcast detector on port {0} ({1}). Reason: {2}", port, a.ToString(), ex.Message), ex);
                                        }
                                    }
                                }
                                if (udpClient != null)
                                {
                                    BroadcastServer server = new BroadcastServer(broadcastEp, udpClient);
                                    mBroadcastServers.Add(server);
                                    server.BeginReceive();
                                }
                            });
                            initUdpClient(AddressFamily.InterNetwork);
                            if (NetworkManager.Instance.InternalConfiguration.Settings.EnableIPV6)
                            {
                                initUdpClient(AddressFamily.InterNetworkV6);
                            }
                        }
                    }
                }
                {
                    // UDP üzenetek szétszórása a hálózatba
                    List <int> targetPorts = NetworkManager.Instance.InternalConfiguration.NetworkPeering.UDPDetection.BroadcastTargetPorts;
                    if (targetPorts.Count > 0)
                    {
                        AddressEndPoint[] addressEps = null;
                        AddressEndPoint[] ipEps      = null;
                        if (NetworkManager.Instance.InternalLocalhost.NATGatewayCollection.NATGateways.Count > 0)
                        {
                            addressEps = new AddressEndPoint[NetworkManager.Instance.InternalLocalhost.NATGatewayCollection.NATGateways.Count];
                            for (int i = 0; i < addressEps.Length; i++)
                            {
                                addressEps[i] = NetworkManager.Instance.InternalLocalhost.NATGatewayCollection.NATGateways[i].EndPoint;
                            }
                        }
                        if (NetworkManager.Instance.InternalLocalhost.TCPServerCollection.TCPServers.Count > 0)
                        {
                            ipEps = new AddressEndPoint[NetworkManager.Instance.InternalLocalhost.TCPServerCollection.TCPServers.Count];
                            for (int i = 0; i < ipEps.Length; i++)
                            {
                                ipEps[i] = NetworkManager.Instance.InternalLocalhost.TCPServerCollection.TCPServers[i].EndPoint;
                            }
                        }
                        if (addressEps != null || ipEps != null)
                        {
                            using (MemoryStream ms = new MemoryStream())
                            {
                                {
                                    UdpBroadcastMessage message = new UdpBroadcastMessage(NetworkManager.Instance.InternalLocalhost.Id,
                                                                                          NetworkManager.Instance.InternalLocalhost.NetworkContext.Name, addressEps, ipEps);
                                    MessageFormatter <UdpBroadcastMessage> formatter = new MessageFormatter <UdpBroadcastMessage>();
                                    formatter.Write(ms, message);
                                    ms.Position = 0;
                                }

                                // multicast
                                if (NetworkManager.Instance.InternalConfiguration.NetworkPeering.UDPDetection.DetectionMode == UDPDetectionModeEnum.Multicast)
                                {
                                    // multicast
                                    foreach (int port in targetPorts)
                                    {
                                        Action <AddressFamily, string> sendMulticastUdpClient = ((a, ip) =>
                                        {
                                            using (System.Net.Sockets.UdpClient udpClient = new System.Net.Sockets.UdpClient(a))
                                            {
                                                udpClient.MulticastLoopback = true;
                                                udpClient.EnableBroadcast = true;
                                                udpClient.AllowNatTraversal(true);
                                                try
                                                {
                                                    IPAddress multicastaddress = IPAddress.Parse(ip);
                                                    udpClient.JoinMulticastGroup(multicastaddress);
                                                    IPEndPoint remoteEp = new IPEndPoint(multicastaddress, port);
                                                    if (LOGGER.IsInfoEnabled)
                                                    {
                                                        LOGGER.Info(string.Format("CONNECTION_MANAGER, sending multicast message on port {0}. ({1})", port, a.ToString()));
                                                    }
                                                    udpClient.Send(ms.ToArray(), Convert.ToInt32(ms.Length), remoteEp);
                                                    udpClient.DropMulticastGroup(multicastaddress);
                                                }
                                                catch (Exception ex)
                                                {
                                                    if (LOGGER.IsErrorEnabled)
                                                    {
                                                        LOGGER.Error(string.Format("CONNECTION_MANAGER, failed to send multicast message ({0}). Reason: {1}", a.ToString(), ex.Message));
                                                    }
                                                }
                                            }
                                        });
                                        if (!string.IsNullOrEmpty(NetworkManager.Instance.InternalConfiguration.NetworkPeering.UDPDetection.IPv4MulticastAddress))
                                        {
                                            sendMulticastUdpClient(AddressFamily.InterNetwork, NetworkManager.Instance.InternalConfiguration.NetworkPeering.UDPDetection.IPv4MulticastAddress);
                                        }
                                        if (NetworkManager.Instance.InternalConfiguration.Settings.EnableIPV6 && !string.IsNullOrEmpty(NetworkManager.Instance.InternalConfiguration.NetworkPeering.UDPDetection.IPv6MulticastAddress))
                                        {
                                            sendMulticastUdpClient(AddressFamily.InterNetworkV6, NetworkManager.Instance.InternalConfiguration.NetworkPeering.UDPDetection.IPv6MulticastAddress);
                                        }
                                    }
                                }
                                else
                                {
                                    // broadcast
                                    using (System.Net.Sockets.UdpClient udpClient = new System.Net.Sockets.UdpClient())
                                    {
                                        udpClient.MulticastLoopback = false;
                                        udpClient.EnableBroadcast   = true;
                                        udpClient.AllowNatTraversal(true);
                                        udpClient.DontFragment = true;
                                        foreach (int port in targetPorts)
                                        {
                                            try
                                            {
                                                if (LOGGER.IsInfoEnabled)
                                                {
                                                    LOGGER.Info(string.Format("CONNECTION_MANAGER, sending broadcast message on port {0}.", port));
                                                }
                                                udpClient.Send(ms.ToArray(), Convert.ToInt32(ms.Length), new IPEndPoint(IPAddress.Broadcast, port));
                                            }
                                            catch (Exception ex)
                                            {
                                                if (LOGGER.IsErrorEnabled)
                                                {
                                                    LOGGER.Error(string.Format("CONNECTION_MANAGER, failed to send broadcast message. Reason: {0}", ex.Message));
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (LOGGER.IsInfoEnabled)
                            {
                                LOGGER.Info("CONNECTION_MANAGER, both of list NAT gateways and TCP servers are empties for broadcast detection.");
                            }
                        }
                    }
                    else
                    {
                        if (LOGGER.IsInfoEnabled)
                        {
                            LOGGER.Info("CONNECTION_MANAGER, no target udp port definied for broadcast detection.");
                        }
                    }
                }
            }
            else
            {
                if (LOGGER.IsInfoEnabled)
                {
                    LOGGER.Info("CONNECTION_MANAGER, broadcast detection disabled.");
                }
            }
        }
Exemple #3
0
        private static void ConnectionTask(object state)
        {
            UdpBroadcastMessage message = (UdpBroadcastMessage)state;

            if (LOGGER.IsDebugEnabled)
            {
                LOGGER.Debug(string.Format("BROADCAST_SERVER, processing message of sender, id: {0}", message.SenderId));
            }
            if (message.TCPServers != null && message.TCPServers.Length > 0)
            {
                foreach (AddressEndPoint ep in message.TCPServers)
                {
                    if (ep.AddressFamily == AddressFamily.InterNetwork || (ep.AddressFamily == AddressFamily.InterNetworkV6 && NetworkManager.Instance.InternalConfiguration.Settings.EnableIPV6))
                    {
                        try
                        {
                            if (LOGGER.IsInfoEnabled)
                            {
                                LOGGER.Info(string.Format("BROADCAST_SERVER, connecting to [{0}] with address [{1}] and port {2}.", message.SenderId, ep.Host, ep.Port));
                            }
                            Synapse.NetworkStream stream = NetworkManager.Instance.InternalNetworkManager.Connect(ep);
                            stream.SendBufferSize    = NetworkManager.Instance.InternalConfiguration.Settings.DefaultLowLevelSocketSendBufferSize;
                            stream.ReceiveBufferSize = NetworkManager.Instance.InternalConfiguration.Settings.DefaultLowLevelSocketReceiveBufferSize;
                            stream.NoDelay           = NetworkManager.Instance.InternalConfiguration.Settings.DefaultLowLevelNoDelay;
                            NetworkPeerRemote remotePeer = NetworkManager.Instance.ProcessConnection(stream, NetworkManager.Instance.InternalConfiguration.Settings.DefaultConnectionTimeoutInMS, true, !NetworkManager.Instance.InternalConfiguration.Settings.EnableMultipleConnectionWithNetworkPeers);
                            if (NetworkManager.Instance.IsShutdown)
                            {
                                stream.Close();
                                break;
                            }
                            if (remotePeer != null && remotePeer.Id.Equals(message.SenderId))
                            {
                                // létrejött a kapcsolat, tovább nem próbálkozunk
                                if (LOGGER.IsInfoEnabled)
                                {
                                    LOGGER.Info(string.Format("BROADCAST_SERVER, successfully connected to '{0}' on TCP server.", message.SenderId));
                                }
                                break;
                            }
                        }
                        catch (Exception ex)
                        {
                            if (LOGGER.IsErrorEnabled)
                            {
                                LOGGER.Error(string.Format("BROADCAST_SERVER, failed to connect to [{0}] with address [{1}] and port {2}. Reason: {3}", message.SenderId, ep.Host, ep.Port, ex.Message));
                            }
                        }
                    }
                    else
                    {
                        if (LOGGER.IsInfoEnabled)
                        {
                            LOGGER.Info(string.Format("BROADCAST_SERVER, connecting to [{0}] with address [{1}] not allowed. IPV6 protocol disabled.", message.SenderId, ep.Host));
                        }
                    }
                }
            }
            INetworkPeerRemote peer = NetworkPeerContext.GetNetworkPeerById(message.SenderId);

            if (peer == null || (peer != null && peer.Distance != 1))
            {
                if (message.NATGateways != null && message.NATGateways.Length > 0)
                {
                    foreach (AddressEndPoint ep in message.NATGateways)
                    {
                        if (ep.AddressFamily == AddressFamily.InterNetwork || (ep.AddressFamily == AddressFamily.InterNetworkV6 && NetworkManager.Instance.InternalConfiguration.Settings.EnableIPV6))
                        {
                            try
                            {
                                if (LOGGER.IsInfoEnabled)
                                {
                                    LOGGER.Info(string.Format("BROADCAST_SERVER, connecting to [{0}] with NAT address [{1}] and port {2}.", message.SenderId, ep.Host, ep.Port));
                                }
                                Synapse.NetworkStream stream = NetworkManager.Instance.InternalNetworkManager.Connect(ep);
                                stream.SendBufferSize    = NetworkManager.Instance.InternalConfiguration.Settings.DefaultLowLevelSocketSendBufferSize;
                                stream.ReceiveBufferSize = NetworkManager.Instance.InternalConfiguration.Settings.DefaultLowLevelSocketReceiveBufferSize;
                                stream.NoDelay           = NetworkManager.Instance.InternalConfiguration.Settings.DefaultLowLevelNoDelay;
                                NetworkPeerRemote remotePeer = NetworkManager.Instance.ProcessConnection(stream, NetworkManager.Instance.InternalConfiguration.Settings.DefaultConnectionTimeoutInMS, true, !NetworkManager.Instance.InternalConfiguration.Settings.EnableMultipleConnectionWithNetworkPeers);
                                if (NetworkManager.Instance.IsShutdown)
                                {
                                    stream.Close();
                                    break;
                                }
                                if (remotePeer != null && remotePeer.Id.Equals(message.SenderId))
                                {
                                    // létrejött a kapcsolat, tovább nem próbálkozunk
                                    if (LOGGER.IsInfoEnabled)
                                    {
                                        LOGGER.Info(string.Format("BROADCAST_SERVER, successfully connected to '{0}' on NAT address.", message.SenderId));
                                    }
                                    break;
                                }
                            }
                            catch (Exception ex)
                            {
                                if (LOGGER.IsErrorEnabled)
                                {
                                    LOGGER.Error(string.Format("BROADCAST_SERVER, failed to connect to [{0}] with address [{1}] and port {2}. Reason: {3}", message.SenderId, ep.Host, ep.Port, ex.Message));
                                }
                            }
                        }
                        else
                        {
                            if (LOGGER.IsInfoEnabled)
                            {
                                LOGGER.Info(string.Format("BROADCAST_SERVER, connecting to [{0}] with address [{1}] not allowed. IPV6 protocol disabled.", message.SenderId, ep.Host));
                            }
                        }
                    }
                }
            }
        }