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(); } }
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."); } } }
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)); } } } } } }