/// <summary> /// Create a new netIO class using a given socket. /// </summary> /// <param name="sock">The socket for this netIO class.</param> public NetIO(Socket sock, Dictionary<ushort, Packet> commandTable, Client client ,ClientManager manager) { this.sock = sock; this.stream = new NetworkStream(sock); this.commandTable = commandTable; this.client = client; this.currentClientManager = manager; Crypt = new Encryption(); this.callbackSize = new AsyncCallback(this.ReceiveSize); this.callbackData = new AsyncCallback(this.ReceiveData); this.callbackKeyExchange= new AsyncCallback(this.ReceiveKeyExchange); // Use the static key untill the keys have been exchanged this.isDisconnected = false; }
/// <summary> /// Create a new netIO class using a given socket. /// </summary> /// <param name="sock">The socket for this netIO class.</param> public NetIO(Socket sock, Dictionary<ushort, Packet> commandTable, Client client ,ClientManager manager) { this.sock = sock; this.stream = new NetworkStream(sock); this.commandTable = commandTable; this.client = client; this.currentClientManager = manager; this.callbackSize = new AsyncCallback(this.ReceiveSize); this.callbackData = new AsyncCallback(this.ReceiveData); this.nlock = new ReaderWriterLock(); // Use the static key untill the keys have been exchanged this.clientKey = new byte[16]; Encryption.StaticKey.CopyTo(this.clientKey, 0); this.serverKey = new byte[16]; Encryption.StaticKey.CopyTo(this.serverKey, 0); this.isDisconnected = false; // Receive the size of the next packet and call ReceiveSize when finished if (sock.Connected) { try { stream.BeginRead(buffer, 0, 2, this.callbackSize, null); } catch (Exception ex) { Logger.ShowError(ex, null); try//this could crash the gateway somehow,so better ignore the Exception { this.Disconnect(); } catch (Exception) { } Logger.ShowWarning("Invalid packet head from:" + sock.RemoteEndPoint.ToString(), null); return; } } else { this.Disconnect(); return; } }
/// <summary> /// Create a new netIO class using a given socket. /// </summary> /// <param name="sock">The socket for this netIO class.</param> public NetIO(Socket sock, Dictionary <ushort, Packet> commandTable, Client client, ClientManager manager) { this.sock = sock; this.stream = new NetworkStream(sock); this.commandTable = commandTable; this.client = client; this.currentClientManager = manager; Crypt = new Encryption(); this.callbackSize = new AsyncCallback(this.ReceiveSize); this.callbackData = new AsyncCallback(this.ReceiveData); this.callbackKeyExchange = new AsyncCallback(this.ReceiveKeyExchange); // Use the static key untill the keys have been exchanged this.isDisconnected = false; }
private void ReceiveData(IAsyncResult ar) { try { if (this.isDisconnected) { return; } if (!sock.Connected) { ClientManager.EnterCriticalArea(); this.Disconnect(); ClientManager.LeaveCriticalArea(); return; } try { stream.EndRead(ar); } catch (Exception) { ClientManager.EnterCriticalArea(); this.Disconnect(); ClientManager.LeaveCriticalArea(); return; } byte[] raw = (byte[])ar.AsyncState; if (alreadyReceived < lastSize) { int left = lastSize - alreadyReceived; if (left > 1024) { left = 1024; } if (left > sock.Available) { left = sock.Available; } try { stream.BeginRead(raw, 4 + alreadyReceived, left, this.callbackData, raw); } catch (Exception ex) { Logger.ShowError(ex); ClientManager.EnterCriticalArea(); this.Disconnect(); ClientManager.LeaveCriticalArea(); return; } alreadyReceived += left; return; } raw = Crypt.Decrypt(raw, 8); Packet p = new Packet(); p.data = raw; uint length = p.GetUInt(4); uint offset = 0; while (offset < length) { uint size; if (firstLevelLenth == 4) { size = p.GetUInt((ushort)(8 + offset)); } else { size = p.GetUShort((ushort)(8 + offset)); } offset += firstLevelLenth; if (size + offset > length) { break; } Packet p2 = new Packet(); p2.data = p.GetBytes((ushort)size, (ushort)(8 + offset)); offset += size; ProcessPacket(p2); } try { stream.BeginRead(buffer, 0, 4, this.callbackSize, null); } catch (Exception) { ClientManager.EnterCriticalArea(); this.Disconnect(); ClientManager.LeaveCriticalArea(); return; } } catch (Exception e) { Logger.ShowError(e, null); } }
private void ReceiveSize(IAsyncResult ar) { try { if (this.isDisconnected) { return; } if (buffer[0] == 0xFF && buffer[1] == 0xFF & buffer[2] == 0xFF && buffer[3] == 0xFF) { // if the buffer is marked as "empty", there was an error during reading // normally happens if the client disconnects // note: this is required as sock.Connected still can be true, even the client // is already disconnected ClientManager.EnterCriticalArea(); this.Disconnect(); ClientManager.LeaveCriticalArea(); return; } if (!sock.Connected) { ClientManager.EnterCriticalArea(); this.Disconnect(); ClientManager.LeaveCriticalArea(); return; } try { stream.EndRead(ar); } catch (Exception) { ClientManager.EnterCriticalArea(); this.Disconnect(); ClientManager.LeaveCriticalArea(); return; } Array.Reverse(buffer); uint size = BitConverter.ToUInt32(buffer, 0) + 4; if (size < 4) { Logger.ShowWarning(sock.RemoteEndPoint.ToString() + " error: packet size is < 4", null); return; } /*while (sock.Available+4 < size) * { * //Logger.ShowWarning(sock.RemoteEndPoint.ToString() + string.Format(" error: packet data is too short, should be {0:G}", size - 2), null); * Thread.Sleep(100); * }*/ byte[] data = new byte[size + 4]; // mark buffer as "empty" buffer[0] = 0xFF; buffer[1] = 0xFF; buffer[2] = 0xFF; buffer[3] = 0xFF; lastSize = (int)size; if (sock.Available < lastSize) { size = (uint)sock.Available; } if (size > 1024) { size = 1024; alreadyReceived = 1024; } else { alreadyReceived = (int)size; } // Receive the data from the packet and call the receivedata function // The packet is stored in AsyncState //Console.WriteLine("New packet with size " + p.size); try { stream.BeginRead(data, 4, (int)(size), this.callbackData, data); } catch (Exception ex) { ClientManager.EnterCriticalArea(); this.Disconnect(); ClientManager.LeaveCriticalArea(); return; } } catch (Exception e) { Logger.ShowError(e, null); } }
private void ReceiveKeyExchange(IAsyncResult ar) { try { if (this.isDisconnected) { return; } if (!sock.Connected) { ClientManager.EnterCriticalArea(); this.Disconnect(); ClientManager.LeaveCriticalArea(); return; } try { stream.EndRead(ar); } catch (Exception) { ClientManager.EnterCriticalArea(); this.Disconnect(); ClientManager.LeaveCriticalArea(); return; } byte[] raw = (byte[])ar.AsyncState; if (raw.Length == 8) { Packet p1 = new Packet(529); p1.PutUInt(1, 4); p1.PutByte(0x32, 8); p1.PutUInt(0x100, 9); Crypt.MakePrivateKey(); string bufstring = Conversions.bytes2HexString(Encryption.Module.getBytes()); p1.PutBytes(System.Text.Encoding.ASCII.GetBytes(bufstring.ToLower()), 13); p1.PutUInt(0x100, 269); bufstring = Conversions.bytes2HexString(Crypt.GetKeyExchangeBytes()); p1.PutBytes(System.Text.Encoding.ASCII.GetBytes(bufstring), 273); SendPacket(p1, true, true); try { byte[] data = new byte[260]; stream.BeginRead(data, 0, 260, this.callbackKeyExchange, data); } catch (Exception) { ClientManager.EnterCriticalArea(); this.Disconnect(); ClientManager.LeaveCriticalArea(); return; } } else if (raw.Length == 260) { Packet p1 = new Packet(); p1.data = raw; byte[] keyBuf = p1.GetBytes(256, 4); Crypt.MakeAESKey(System.Text.Encoding.ASCII.GetString(keyBuf)); StartPacketParsing(); } else if (raw.Length == 529) { Packet p1 = new Packet(); p1.data = raw; byte[] keyBuf = p1.GetBytes(256, 273); Crypt.MakePrivateKey(); Packet p2 = new Packet(260); p2.PutUInt(0x100, 0); string bufstring = Conversions.bytes2HexString(Crypt.GetKeyExchangeBytes()); p2.PutBytes(System.Text.Encoding.ASCII.GetBytes(bufstring), 4); SendPacket(p2, true, true); Crypt.MakeAESKey(System.Text.Encoding.ASCII.GetString(keyBuf)); StartPacketParsing(); } } catch (Exception ex) { Logger.ShowError(ex); } }
/// <summary> /// Create a new netIO class using a given socket. /// </summary> /// <param name="sock">The socket for this netIO class.</param> public NetIO(Socket sock, Dictionary <ushort, Packet> commandTable, Client client, ClientManager manager) { this.sock = sock; this.stream = new NetworkStream(sock); this.commandTable = commandTable; this.client = client; this.currentClientManager = manager; this.callbackSize = new AsyncCallback(this.ReceiveSize); this.callbackData = new AsyncCallback(this.ReceiveData); this.nlock = new ReaderWriterLock(); // Use the static key untill the keys have been exchanged this.clientKey = new byte[16]; Encryption.StaticKey.CopyTo(this.clientKey, 0); this.serverKey = new byte[16]; Encryption.StaticKey.CopyTo(this.serverKey, 0); this.isDisconnected = false; // Receive the size of the next packet and call ReceiveSize when finished if (sock.Connected) { try { stream.BeginRead(buffer, 0, 2, this.callbackSize, null); } catch (Exception ex) { Logger.ShowError(ex, null); try//this could crash the gateway somehow,so better ignore the Exception { this.Disconnect(); } catch (Exception) { } Logger.ShowWarning("Paquete invalido de:" + sock.RemoteEndPoint.ToString(), null); return; } } else { this.Disconnect(); return; } }
private void ReceiveData(IAsyncResult ar) { try { this.nlock.AcquireWriterLock(Timeout.Infinite); if (this.isDisconnected) { this.nlock.ReleaseWriterLock(); return; } if (!sock.Connected) { this.nlock.ReleaseWriterLock(); ClientManager.EnterCriticalArea(); this.Disconnect(); ClientManager.LeaveCriticalArea(); return; } try { stream.EndRead(ar); } catch (Exception) { this.nlock.ReleaseWriterLock(); ClientManager.EnterCriticalArea(); this.Disconnect(); ClientManager.LeaveCriticalArea(); return; } byte[] raw = (byte[])ar.AsyncState; if (this.isGateway) { raw = Encryption.Decrypt(raw, 2, this.ClientKey); } if (!isGateway) { ushort messageID = (ushort)(raw[7] + (raw[6] << 8)); if (!this.commandTable.ContainsKey((messageID))) { if (!this.fullHeader) { Logger.ShowWarning(string.Format("Un paquete desconocido {0:X} {1:X} desde " + sock.RemoteEndPoint.ToString(), raw[6], raw[7]), null); } else { if (commandTable.ContainsKey((ushort)0xFFFF)) { if (this.commandTable[(ushort)0xFFFF].SizeIsOk((ushort)raw.Length)) { Packet p = this.commandTable[(ushort)0xFFFF].New(); p.data = raw; p.size = (ushort)(raw.Length); ClientManager.EnterCriticalArea(); try { p.Parse(this.client); } catch (Exception ex) { Logger.ShowError(ex); } ClientManager.LeaveCriticalArea(); } else { string error = "Paquete invalido del cliente " + sock.RemoteEndPoint.ToString(); Console.WriteLine(error); Log.WriteLog(error); ClientManager.EnterCriticalArea(); this.Disconnect(); ClientManager.LeaveCriticalArea(); return; } } else { Logger.ShowWarning("Paquete universal 0xFFFF no definido!", null); } } } else { if (this.commandTable[messageID].SizeIsOk((ushort)raw.Length)) { Packet p = this.commandTable[messageID].New(); p.data = raw; p.size = (ushort)(raw.Length); Client client; if (p.SessionID != 0) { client = this.currentClientManager.GetClient(p.SessionID); if (client == null) { client = this.client; } } else { client = this.client; } ClientManager.EnterCriticalArea(); try { if (client.netIO == null) { client.netIO = this; } p.Parse(client); } catch (Exception ex) { Logger.ShowError(ex); } ClientManager.LeaveCriticalArea(); } else { string error = string.Format("Tamano del paquete invalido (Paquete:{0:X4}) de cliente {1}", messageID, sock.RemoteEndPoint.ToString()); Console.WriteLine(error); Log.WriteLog(error); this.nlock.ReleaseWriterLock(); ClientManager.EnterCriticalArea(); this.Disconnect(); ClientManager.LeaveCriticalArea(); return; } } } else { ushort messageID; if (!fullHeader) { messageID = (ushort)(raw[7] + (raw[6] << 8)); if (!this.commandTable.ContainsKey((messageID))) { Logger.ShowWarning(string.Format("Se ha obtenido un paquete desconocido {0:X} {1:X} desde " + sock.RemoteEndPoint.ToString(), raw[6], raw[7]), null); } else { if (this.commandTable[messageID].SizeIsOk((ushort)raw.Length)) { Packet p = this.commandTable[messageID].New(); p.data = raw; p.size = (ushort)(raw.Length); p.isGateway = this.isGateway; ClientManager.EnterCriticalArea(); try { p.Parse(this.client); } catch (Exception ex) { Logger.ShowError(ex); } ClientManager.LeaveCriticalArea(); } else { string error = "Invalid packet size from client " + sock.RemoteEndPoint.ToString(); Console.WriteLine(error); Log.WriteLog(error); this.nlock.ReleaseWriterLock(); ClientManager.EnterCriticalArea(); this.Disconnect(); ClientManager.LeaveCriticalArea(); return; } } } else { if (commandTable.ContainsKey((ushort)0xFFFF)) { if (this.commandTable[(ushort)0xFFFF].SizeIsOk((ushort)raw.Length)) { Packet p = this.commandTable[(ushort)0xFFFF].New(); p.data = raw; p.size = (ushort)(raw.Length); p.isGateway = this.isGateway; ClientManager.EnterCriticalArea(); try { p.Parse(this.client); } catch (Exception ex) { Logger.ShowError(ex); } ClientManager.LeaveCriticalArea(); } else { string error = "Invalid packet size from client " + sock.RemoteEndPoint.ToString(); Console.WriteLine(error); Log.WriteLog(error); this.nlock.ReleaseWriterLock(); ClientManager.EnterCriticalArea(); this.Disconnect(); ClientManager.LeaveCriticalArea(); return; } } else { Logger.ShowWarning("Universal Packet 0xFFFF not defined!", null); } } } try { this.nlock.ReleaseWriterLock(); stream.BeginRead(buffer, 0, 2, this.callbackSize, null); } catch (Exception) { ClientManager.EnterCriticalArea(); this.Disconnect(); ClientManager.LeaveCriticalArea(); return; } } catch (Exception e) { Logger.ShowError(e, null); } }
private void ReceiveSize(IAsyncResult ar) { this.nlock.AcquireWriterLock(Timeout.Infinite); try { if (this.isDisconnected) { this.nlock.ReleaseWriterLock(); return; } if (buffer[0] == 0xFF && buffer[1] == 0xFF) { // if the buffer is marked as "empty", there was an error during reading // normally happens if the client disconnects // note: this is required as sock.Connected still can be true, even the client // is already disconnected this.nlock.ReleaseWriterLock(); ClientManager.EnterCriticalArea(); this.Disconnect(); ClientManager.LeaveCriticalArea(); return; } if (!sock.Connected) { this.nlock.ReleaseWriterLock(); ClientManager.EnterCriticalArea(); this.Disconnect(); ClientManager.LeaveCriticalArea(); return; } try { stream.EndRead(ar); } catch (Exception) { this.nlock.ReleaseWriterLock(); ClientManager.EnterCriticalArea(); this.Disconnect(); ClientManager.LeaveCriticalArea(); return; } ushort size = BitConverter.ToUInt16(buffer, 0); if (size < 4) { Logger.ShowWarning(sock.RemoteEndPoint.ToString() + " error: el tamano del paquete es < 4", null); /*try//this could crash the gateway somehow,so better ignore the Exception * { * ClientManager.EnterCriticalArea(); * this.Disconnect(); * ClientManager.LeaveCriticalArea(); * } * catch (Exception ex) * { * Logger.ShowError(ex, null); * //sock.Disconnect(true); * sock.Close(); * ClientManager.LeaveCriticalArea(); * }*/ this.nlock.ReleaseWriterLock(); return; } if (sock.Available < (size - 2)) { Logger.ShowWarning(sock.RemoteEndPoint.ToString() + string.Format(" error: los datos del paquete son demaciados cortos, debe ser {0:G}", size - 2), null); /*try//this could crash the gateway somehow,so better ignore the Exception * { * ClientManager.EnterCriticalArea(); * this.Disconnect(); * ClientManager.LeaveCriticalArea(); * } * catch (Exception) * { * //sock.Disconnect(true); * sock.Close(); * ClientManager.LeaveCriticalArea(); * }*/ //this.nlock.ReleaseWriterLock(); //return; } byte[] data = new byte[size]; data[0] = buffer[0]; data[1] = buffer[1]; // mark buffer as "empty" buffer[0] = 0xFF; buffer[1] = 0xFF; // Receive the data from the packet and call the receivedata function // The packet is stored in AsyncState //Console.WriteLine("New packet with size " + p.size); try { this.nlock.ReleaseWriterLock(); stream.BeginRead(data, 2, size - 2, this.callbackData, data); } catch (Exception) { //Logger.ShowError(ex, null); ClientManager.EnterCriticalArea(); this.Disconnect(); ClientManager.LeaveCriticalArea(); return; } } catch (Exception e) { Logger.ShowError(e, null); } }