/// <summary> /// Initializes a new instance of the <see cref="NetworkGateway"/> class. /// </summary> public static void Initialize() { if (NetworkTcp.Initialized) { return; } NetworkTcp.FillPools(); NetworkTcp.Listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); NetworkTcp.Listener.NoDelay = true; NetworkTcp.Listener.Blocking = false; NetworkTcp.Initialized = true; NetworkTcp.Listener.Bind(new IPEndPoint(IPAddress.Any, 9339)); NetworkTcp.Listener.Listen(150); Logging.Info(typeof(NetworkTcp), "Listener has been bound to " + NetworkTcp.Listener.LocalEndPoint + "."); SocketAsyncEventArgs AcceptEvent = new SocketAsyncEventArgs(); AcceptEvent.Completed += NetworkTcp.OnAcceptCompleted; AcceptEvent.DisconnectReuseSocket = true; NetworkTcp.StartAccept(AcceptEvent); }
/// <summary> /// Processes to send a <see cref="Message"/> using the specified <see cref="SocketAsyncEventArgs"/>. /// </summary> /// <param name="AsyncEvent">The <see cref="SocketAsyncEventArgs"/> instance containing the event data.</param> private static void ProcessSend(SocketAsyncEventArgs AsyncEvent) { NetworkToken Token = (NetworkToken)AsyncEvent.UserToken; if (AsyncEvent.SocketError == SocketError.Success) { if (AsyncEvent.Count > AsyncEvent.BytesTransferred) { int Offset = AsyncEvent.Offset + AsyncEvent.BytesTransferred; if (Token.IsConnected) { AsyncEvent.SetBuffer(Offset, AsyncEvent.Buffer.Length - Offset); if (!Token.Socket.SendAsync(AsyncEvent)) { NetworkTcp.ProcessSend(AsyncEvent); } return; } NetworkTcp.Disconnect(Token.AsyncEvent); } } else { NetworkTcp.Disconnect(Token.AsyncEvent); } NetworkTcp.OnSendCompleted(null, AsyncEvent); }
/// <summary> /// Starts to receive data from remote host. /// </summary> public static void StartReceive(NetworkToken Token) { if (!Token.Socket.ReceiveAsync(Token.AsyncEvent)) { NetworkTcp.ProcessReceive(Token.AsyncEvent); } }
/// <summary> /// Accept the new client and store it in memory. /// </summary> /// <param name="AsyncEvent">The <see cref="SocketAsyncEventArgs"/> instance containing the event data.</param> private static void ProcessAccept(SocketAsyncEventArgs AsyncEvent) { if (AsyncEvent.AcceptSocket.Connected) { string IpAddress = ((IPEndPoint)AsyncEvent.AcceptSocket.RemoteEndPoint).Address.ToString(); if (IpAddress.StartsWith("192.168.")) { SocketAsyncEventArgs ReadEvent = NetworkTcp.ReadPool.Dequeue(); if (ReadEvent != null) { NetworkToken Token = new NetworkToken(ReadEvent, AsyncEvent.AcceptSocket); Device Device = new Device(Token); Devices.Add(Device); if (!Token.Socket.ReceiveAsync(ReadEvent)) { NetworkTcp.ProcessReceive(ReadEvent); } } else { Logging.Warning(typeof(NetworkTcp), "Server is full, new connections cannot be accepted."); } } } NetworkTcp.StartAccept(AsyncEvent); }
/// <summary> /// Accepts a TCP Request. /// </summary> /// <param name="AcceptEvent">The <see cref="SocketAsyncEventArgs"/> instance containing the event data.</param> private static void StartAccept(SocketAsyncEventArgs AcceptEvent) { AcceptEvent.AcceptSocket = null; AcceptEvent.RemoteEndPoint = null; if (!NetworkTcp.Listener.AcceptAsync(AcceptEvent)) { NetworkTcp.OnAcceptCompleted(null, AcceptEvent); } }
/// <summary> /// Called when [receive completed]. /// </summary> /// <param name="Sender">The sender.</param> /// <param name="AsyncEvent">The <see cref="SocketAsyncEventArgs"/> instance containing the event data.</param> private static void OnReceiveCompleted(object Sender, SocketAsyncEventArgs AsyncEvent) { if (AsyncEvent.SocketError == SocketError.Success) { NetworkTcp.ProcessReceive(AsyncEvent); } else { NetworkTcp.Disconnect(AsyncEvent); } }
/// <summary> /// Called when the client has been connected. /// </summary> /// <param name="Sender">The sender.</param> /// <param name="AsyncEvent">The <see cref="SocketAsyncEventArgs"/> instance containing the event data.</param> private static void OnConnectCompleted(object Sender, SocketAsyncEventArgs AsyncEvent) { if (AsyncEvent.SocketError == SocketError.Success) { ((ManualResetEventSlim)AsyncEvent.UserToken).Set(); } else { NetworkTcp.Disconnect(AsyncEvent); } }
/// <summary> /// Called when the client has been accepted. /// </summary> /// <param name="Sender">The sender.</param> /// <param name="AsyncEvent">The <see cref="SocketAsyncEventArgs"/> instance containing the event data.</param> private static void OnAcceptCompleted(object Sender, SocketAsyncEventArgs AsyncEvent) { if (AsyncEvent.SocketError == SocketError.Success) { NetworkTcp.ProcessAccept(AsyncEvent); } else { NetworkTcp.StartAccept(AsyncEvent); } }
/// <summary> /// Connets the specified token to the remote host. /// </summary> public static bool StartConnect(string Host, out NetworkToken Token) { Socket Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); Socket.Blocking = false; Socket.NoDelay = true; var ConnectEvent = new SocketAsyncEventArgs(); ConnectEvent.RemoteEndPoint = new DnsEndPoint(Host, 9339); ManualResetEventSlim Waiter = new ManualResetEventSlim(); ConnectEvent.Completed += NetworkTcp.OnConnectCompleted; ConnectEvent.UserToken = Waiter; if (!Socket.ConnectAsync(ConnectEvent)) { NetworkTcp.OnConnectCompleted(Socket, ConnectEvent); } if (Waiter.Wait(10000)) { var AsyncEvent = NetworkTcp.ReadPool.Dequeue(); if (AsyncEvent != null) { Token = new NetworkToken(AsyncEvent, ConnectEvent.ConnectSocket); Token.AsyncEvent.AcceptSocket = null; Token.AsyncEvent.RemoteEndPoint = new DnsEndPoint(Host, 9339); if (!Token.Socket.ReceiveAsync(Token.AsyncEvent)) { NetworkTcp.ProcessReceive(Token.AsyncEvent); } return(true); } else { Logging.Info(typeof(NetworkTcp), "AsyncEvent == null at StartConnect()."); } } else { Logging.Info(typeof(NetworkTcp), "Waiter.Wait(10000) != true at StartConnect()."); } Token = null; return(false); }
/// <summary> /// Finalizes this instance. /// </summary> public void Process() { byte[] Buffer = this.Packet.ToArray(); if (Buffer.Length >= 7) { this.TcpProcess(Buffer); } else { NetworkTcp.Disconnect(this.AsyncEvent); } }
/// <summary> /// Receives data from the specified client. /// </summary> /// <param name="AsyncEvent">The <see cref="SocketAsyncEventArgs"/> instance containing the event data.</param> private static void ProcessReceive(SocketAsyncEventArgs AsyncEvent) { if (AsyncEvent.BytesTransferred == 0) { NetworkTcp.Disconnect(AsyncEvent); } if (AsyncEvent.SocketError != SocketError.Success) { NetworkTcp.Disconnect(AsyncEvent); } NetworkToken Token = (NetworkToken)AsyncEvent.UserToken; if (Token.IsConnected) { Token.AddData(); try { if (Token.Socket.Available == 0) { Token.Process(); } if (Token.IsFailing == false) { if (!Token.Socket.ReceiveAsync(AsyncEvent)) { NetworkTcp.ProcessReceive(AsyncEvent); } } else { NetworkTcp.Disconnect(AsyncEvent); } } catch (Exception Exception) { Logging.Warning(typeof(NetworkTcp), Exception.GetType().Name + " thrown at ProcessReceive(" + AsyncEvent.RemoteEndPoint + ")."); NetworkTcp.Disconnect(AsyncEvent); } } else { NetworkTcp.Disconnect(AsyncEvent); } }
/// <summary> /// Sends the specified message. /// </summary> /// <param name="Message">The message.</param> public void SendMessage(Message Message) { if (this.Device.Token.IsConnected) { if (Message.IsServerToClientMessage == false) { Message.Encode(); byte[] Decrypted = Message.Stream.ToArray(); byte[] Encrypted = null; if (this.SendEncrypter != null) { Encrypted = this.SendEncrypter.Encrypt(Decrypted); } else { if (this.PepperInit.State > 0) { if (this.PepperInit.State == 2) { this.PepperInit.ServerPublicKey = PepperFactory.PublicKey; Encrypted = PepperCrypto.SendPepperLogin(ref this.PepperInit, Decrypted); } } else { Encrypted = PepperCrypto.SendPepperAuthentification(ref this.PepperInit, Decrypted); } } Message.Stream.SetByteArray(Encrypted); NetworkTcp.Send(Message.ToBytes, this.Device.Token); } else { Logging.Warning(this.GetType(), "ClientToServer != false at SendMessage(Message " + Message.Type + ")."); } } // else { // Logging.Warning(this.GetType(), "[" + this.Device.BotId + "] IsConnected != true at SendMessage(Message " + Message.Type + ")."); } }
/// <summary> /// Sends the specified message. /// </summary> /// <param name="Message">The message.</param> public void SendMessage(Message Message) { Logging.Info(typeof(NetworkTcp), "Sending " + Message.GetType().Name + "."); if (this.Device.Token.IsConnected) { if (Message.IsServerToClientMessage) { Message.Encode(); byte[] Bytes = Message.Stream.ToArray(); if (this.SendEncrypter == null) { if (this.PepperInit.State > 0) { if (this.PepperInit.State == 1) { Bytes = PepperCrypto.SendPepperAuthentificationResponse(ref this.PepperInit, Bytes); } else { if (this.PepperInit.State == 3) { Bytes = PepperCrypto.SendPepperLoginResponse(ref this.PepperInit, out this.SendEncrypter, out this.ReceiveEncrypter, Bytes); } } } } else { Bytes = this.SendEncrypter.Encrypt(Bytes); } Message.Stream.SetByteArray(Bytes); NetworkTcp.Send(this.WriteHeader(Message), this.Device.Token); HandlerFactory.MessageHandle(this.Device, Message); // TODO : Probably call Task.Wait(). } else { Logging.Error(this.GetType(), "Message.IsServerToClientMessage != true at SendMessage(Message " + Message.Type + ")."); } } }
/// <summary> /// Sends the specified message. /// </summary> /// <param name="Message">The message.</param> public void SendMessage(Message Message) { Logging.Info(typeof(NetworkTcp), "Sending " + Message.GetType().Name + " to " + this.Device.Token.Socket.RemoteEndPoint + "."); if (this.Device.Token.IsConnected) { // Message.Encode(); byte[] Bytes = Message.Stream.ToArray(); if (this.SendEncrypter == null) { if (this.PepperInit.State > 0) { if (this.PepperInit.State == 1) { Bytes = PepperCrypto.SendPepperAuthentificationResponse(ref this.PepperInit, Bytes); } else { if (this.PepperInit.State == 3) { Bytes = PepperCrypto.SendPepperLoginResponse(ref this.PepperInit, out this.SendEncrypter, out this.ReceiveEncrypter, Bytes); } } } } else { Bytes = this.SendEncrypter.Encrypt(Bytes); } Message.Stream.SetByteArray(Bytes); Logging.Info(this.GetType(), BitConverter.ToString(Message.ToBytes)); NetworkTcp.Send(Message.ToBytes, this.Device.Token); HandlerFactory.MessageHandle(this.Device, Message).Wait(); } }
/// <summary> /// Sends the specified message. /// </summary> /// <param name="Buffer">The buffer.</param> /// <param name="Token">The token.</param> public static void Send(byte[] Buffer, NetworkToken Token) { if (Buffer == null) { throw new ArgumentNullException(nameof(Message), "Buffer == null at Send(Buffer, Token)."); } if (Token == null) { throw new ArgumentNullException(nameof(Token), "Token == null at Send(Buffer, Token)."); } if (Token.IsConnected) { SocketAsyncEventArgs WriteEvent = NetworkTcp.WritePool.Dequeue(); if (WriteEvent == null) { WriteEvent = new SocketAsyncEventArgs { DisconnectReuseSocket = false }; } WriteEvent.SetBuffer(Buffer, 0, Buffer.Length); WriteEvent.AcceptSocket = Token.Socket; WriteEvent.RemoteEndPoint = Token.Socket.RemoteEndPoint; WriteEvent.UserToken = Token; if (!Token.Socket.SendAsync(WriteEvent)) { NetworkTcp.ProcessSend(WriteEvent); } } else { NetworkTcp.Disconnect(Token.AsyncEvent); } }
/// <summary> /// Receives the message. /// </summary> public void ReceiveMessage(short Type, short Version, byte[] Packet) { if (this.ReceiveEncrypter == null) { if (this.PepperInit.State == 0) { if (Type == 10101) { this.SendEncrypter = new Rc4Encrypter("fhsd6f86f67rt8fw78fw789we78r9789wer6re", "nonce"); this.ReceiveEncrypter = new Rc4Encrypter("fhsd6f86f67rt8fw78fw789we78r9789wer6re", "nonce"); Packet = this.ReceiveEncrypter.Decrypt(Packet); } else if (Type == 10100) { Packet = PepperCrypto.HandlePepperAuthentification(ref this.PepperInit, Packet); } else { Packet = null; } } else { if (this.PepperInit.State == 2) { Packet = Type == 10101 ? PepperCrypto.HandlePepperLogin(ref this.PepperInit, Packet) : null; } else { Packet = null; } } } else { Packet = this.ReceiveEncrypter.Decrypt(Packet); } if (Packet != null) { if (this.Device.State != State.Logged) { if (Type != 10100 && Type != 10101) { if (++this.InvalidMessageStateCnt >= 5) { NetworkTcp.Disconnect(this.Device.Token.AsyncEvent); } return; } } using (ByteStream Stream = new ByteStream(Packet)) { Message Message = MessageFactory.CreateMessage(Type, Stream); if (Message != null) { Logging.Info(this.GetType(), "Receiving " + Message.GetType().Name + "."); if (this.RequestTime.CanHandleMessage(Message)) { try { Message.Decode(); } catch (Exception Exception) { Logging.Error(this.GetType(), "ReceiveMessage() - An error has been throwed when the message type " + Message.Type + " has been processed. " + Exception); } HandlerFactory.MessageHandle(this.Device, Message); // TODO : Probably call Task.Wait(). } } else { Logging.Info(this.GetType(), BitConverter.ToString(Stream.ReadBytes(Stream.BytesLeft))); } } } else { if (this.Device.State == State.Logged) { Logging.Error(this.GetType(), "Packet == null at ReceiveMessage()."); } } }