[System.Diagnostics.DebuggerHidden] //fix netcore log with TimeoutExceptions private void ReceiveLogic(object state) { Socket socket = (Socket)state; EndPoint bufferEndPoint = new IPEndPoint(socket.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any, 0); byte[] receiveBuffer = new byte[NetConstants.MaxPacketSize]; while (_running) { int result; //Reading data try { if (socket.Available == 0 && !socket.Poll(5000, SelectMode.SelectRead)) { continue; } result = socket.ReceiveFrom(receiveBuffer, 0, receiveBuffer.Length, SocketFlags.None, ref bufferEndPoint); } catch (SocketException ex) { switch (ex.SocketErrorCode) { case SocketError.Interrupted: return; case SocketError.ConnectionReset: case SocketError.MessageSize: case SocketError.TimedOut: NetUtils.DebugWriteForce(ConsoleColor.DarkRed, "[R] Ingored error: {0} - {1}", (int)ex.SocketErrorCode, ex.ToString()); break; default: NetUtils.DebugWriteError("[R]Error code: {0} - {1}", (int)ex.SocketErrorCode, ex.ToString()); _listener.OnMessageReceived(null, 0, ex.SocketErrorCode, (IPEndPoint)bufferEndPoint); break; } continue; } catch (ObjectDisposedException) { return; } //All ok! NetUtils.DebugWrite(ConsoleColor.Blue, "[R]Received data from {0}, result: {1}", bufferEndPoint.ToString(), result); _listener.OnMessageReceived(receiveBuffer, result, 0, (IPEndPoint)bufferEndPoint); } }
internal void DebugWriteForce(string str, params object[] args) { NetUtils.DebugWriteForce(DebugTextColor, str, args); }
protected override void ReceiveFromSocket(byte[] reusableBuffer, int count, NetEndPoint remoteEndPoint) { //Parse packet //Peer null when P2P connection packets NetPacket packet = _peer == null ? new NetPacket() : _peer.GetPacketFromPool(init: false); if (!packet.FromBytes(reusableBuffer, count)) { if (_peer != null) { _peer.Recycle(packet); } return; } //Check P2P mode if (PeerToPeerMode && packet.Property == PacketProperty.ConnectRequest) { NetUtils.DebugWrite(ConsoleColor.Cyan, "[NC] Received peer connect request"); string peerKey = Encoding.UTF8.GetString(packet.RawData, 9, packet.RawData.Length - 9); if (peerKey != _connectKey) { NetUtils.DebugWrite(ConsoleColor.Cyan, "[NC] Peer connect reject. Invalid key: " + peerKey); return; } NetUtils.DebugWrite(ConsoleColor.Cyan, "[NC] Peer connect accepting"); //Make initial packet and put id from received packet var connectPacket = NetPacket.CreateRawPacket(PacketProperty.ConnectAccept, 8); Buffer.BlockCopy(packet.RawData, 1, connectPacket, 1, 8); //Check our peer and create if (_peer == null) { //Create connect id for proper connection Connect(remoteEndPoint); } //Send raw _peer.SendRawData(connectPacket); //clean incoming packet _peer.Recycle(packet); //We connected ProcessConnectAccept(); return; } //Check peer if (_peer == null) { return; } //Check endpoint if (!_peer.EndPoint.Equals(remoteEndPoint)) { NetUtils.DebugWriteForce(ConsoleColor.DarkCyan, "[NC] Bad EndPoint " + remoteEndPoint); return; } if (packet.Property == PacketProperty.Disconnect) { NetUtils.DebugWrite(ConsoleColor.Cyan, "[NC] Received disconnection"); CloseConnection(true); var disconnectEvent = CreateEvent(NetEventType.Disconnect); disconnectEvent.AdditionalInfo = "Received disconnection from server"; EnqueueEvent(disconnectEvent); return; } if (packet.Property == PacketProperty.ConnectAccept) { if (_connected) { return; } //check connection id if (BitConverter.ToUInt64(packet.RawData, 1) != _connectId) { return; } //connection things ProcessConnectAccept(); return; } //Process income packet _peer.ProcessPacket(packet); }
private void DataReceived(byte[] reusableBuffer, int count, NetEndPoint remoteEndPoint) { #if STATS_ENABLED Statistics.PacketsReceived++; Statistics.BytesReceived += (uint)count; #endif //Try read packet NetPacket packet = NetPacketPool.GetAndRead(reusableBuffer, 0, count); if (packet == null) { NetUtils.DebugWriteError("[NM] DataReceived: bad!"); return; } //Check unconnected switch (packet.Property) { case PacketProperty.DiscoveryRequest: if (DiscoveryEnabled) { var netEvent = CreateEvent(NetEventType.DiscoveryRequest); netEvent.RemoteEndPoint = remoteEndPoint; netEvent.DataReader.SetSource(packet.RawData, NetConstants.HeaderSize, count); EnqueueEvent(netEvent); } return; case PacketProperty.DiscoveryResponse: { var netEvent = CreateEvent(NetEventType.DiscoveryResponse); netEvent.RemoteEndPoint = remoteEndPoint; netEvent.DataReader.SetSource(packet.RawData, NetConstants.HeaderSize, count); EnqueueEvent(netEvent); } return; case PacketProperty.UnconnectedMessage: if (UnconnectedMessagesEnabled) { var netEvent = CreateEvent(NetEventType.ReceiveUnconnected); netEvent.RemoteEndPoint = remoteEndPoint; netEvent.DataReader.SetSource(packet.RawData, NetConstants.HeaderSize, count); EnqueueEvent(netEvent); } return; case PacketProperty.NatIntroduction: case PacketProperty.NatIntroductionRequest: case PacketProperty.NatPunchMessage: { if (NatPunchEnabled) { NatPunchModule.ProcessMessage(remoteEndPoint, packet); } return; } } //Check normal packets NetPeer netPeer; lock (_peers) { _peers.TryGetValue(remoteEndPoint, out netPeer); } if (netPeer != null && netPeer.ConnectionState != ConnectionState.Disconnected) { switch (packet.Property) { case PacketProperty.Disconnect: if (netPeer.ConnectionState == ConnectionState.InProgress || netPeer.ConnectionState == ConnectionState.Connected) { if (BitConverter.ToInt64(packet.RawData, 1) != netPeer.ConnectId) { //Old or incorrect disconnect NetPacketPool.Recycle(packet); return; } var netEvent = CreateEvent(NetEventType.Disconnect); netEvent.Peer = netPeer; netEvent.DataReader.SetSource(packet.RawData, 9, packet.Size); netEvent.DisconnectReason = DisconnectReason.RemoteConnectionClose; EnqueueEvent(netEvent); } break; case PacketProperty.ShutdownOk: if (netPeer.ConnectionState != ConnectionState.ShutdownRequested) { return; } netPeer.ProcessPacket(packet); NetUtils.DebugWriteForce(ConsoleColor.Cyan, "[NM] ShutdownOK!"); break; case PacketProperty.ConnectAccept: if (netPeer.ProcessConnectAccept(packet)) { var connectEvent = CreateEvent(NetEventType.Connect); connectEvent.Peer = netPeer; EnqueueEvent(connectEvent); } NetPacketPool.Recycle(packet); return; default: netPeer.ProcessPacket(packet); return; } return; } //Unacked shutdown if (packet.Property == PacketProperty.Disconnect) { byte[] data = { (byte)PacketProperty.ShutdownOk }; SendRaw(data, 0, 1, remoteEndPoint); return; } if (packet.Property == PacketProperty.ConnectRequest && packet.Size >= 12) { int peersCount = GetPeersCount(ConnectionState.Connected | ConnectionState.InProgress); lock (_connectingPeers) { if (_connectingPeers.Contains(remoteEndPoint)) { return; } if (peersCount < _maxConnections) { int protoId = BitConverter.ToInt32(packet.RawData, 1); if (protoId != NetConstants.ProtocolId) { NetUtils.DebugWrite(ConsoleColor.Cyan, "[NM] Peer connect reject. Invalid protocol ID: " + protoId); return; } //Getting new id for peer long connectionId = BitConverter.ToInt64(packet.RawData, 5); // Read data and create request var reader = new NetDataReader(null, 0, 0); if (packet.Size > 12) { reader.SetSource(packet.RawData, 13, packet.Size); } _connectingPeers.Add(remoteEndPoint); var netEvent = CreateEvent(NetEventType.ConnectionRequest); netEvent.ConnectionRequest = new ConnectionRequest(connectionId, remoteEndPoint, reader, OnConnectionSolved); EnqueueEvent(netEvent); } } } }
internal void DebugWriteForce(string str, params object[] args) { NetUtils.DebugWriteForce(ConsoleColor.DarkGreen, str, args); }