protected override bool TryGetRecieveBuffer(IBuffer value, out DataReader reader) { bool blnRet = false; lock (Syncroot) { reader = null; try { if (m_RecieveBuffer == null) { m_RecieveBuffer = new RecieveBuffer(value); } else { m_RecieveBuffer?.Consume(value); } if (m_RecieveBuffer.HeaderComplete && m_RecieveBuffer.UniqueClientID != this.Connection.UniqueClientID) { Log.Warn("Recieved for invalid client id. Data currupt, discarding..."); m_RecieveBuffer = null; } else if (m_RecieveBuffer?.Complete == true) { if (m_RecieveBuffer.UniqueClientID == this.Connection.UniqueClientID) { reader = m_RecieveBuffer.Decrypt(Connection); reader.ByteOrder = ByteOrder.LittleEndian; m_RecieveBuffer = null; if (reader.ReadUInt32() == this.Connection.UniqueClientID.Value) { blnRet = true; } else { Log.Warn("Decryption of message failed (PDATA has wrong UniqueClientID)!"); } } else { Log.Warn("Recieved message for wrong ClientID?!"); } } else { Log.Debug($"Nonce: {m_RecieveBuffer.Nonce}"); Log.Debug($"UniqueClientID: {m_RecieveBuffer.UniqueClientID}"); Log.Debug($"Length: {m_RecieveBuffer.Length}"); Log.Debug($"HeaderComplete: {m_RecieveBuffer.HeaderComplete}"); Log.Debug($"Recieved: {m_RecieveBuffer.Recieved}"); } } catch (Exception ex) { Log.Error("Exception in TryRecieve: " + ex.ToString()); } } return(blnRet); }
protected override Task <bool> Send(SendBaseCommand cmd, DataWriter writer) { bool blnRet = false; lock (Syncroot) m_RecieveBuffer = null; byte[] byNonce = Sodium.Core.GetRandomBytes(24); writer.WriteBytes(byNonce); writer.WriteUInt32(Connection.UniqueClientID.Value); byte[] byDecryptedMessage = cmd.Serialize(BitConverter.GetBytes(Connection.UniqueClientID.Value)).ToArray(); byte[] byEncryptedMessage = Sodium.SecretBox.Create(byDecryptedMessage, byNonce, Connection.SharedKey); writer.WriteUInt16((UInt16)byEncryptedMessage.Length); writer.WriteBytes(byEncryptedMessage); blnRet = true; return(Task.FromResult(blnRet)); }
private async Task RecievePacket(UdpReceiveResult packet) { long startAbsolutePosition; switch ((CommandCode)packet.Buffer[0]) { case CommandCode.ConnectAck: lock (this) { state = ClientSocketState.Working; Monitor.Pulse(this); } LastRecieved = DateTime.Now; Console.WriteLine($"Connect acked"); break; case CommandCode.Data: Console.WriteLine($"Incoming data"); startAbsolutePosition = BitConverter.ToInt64(packet.Buffer, 1); LastRecieved = DateTime.Now; bool added; lock (RecieveBuffer) { try { added = RecieveBuffer.TryAdd(packet.Buffer, 9, packet.Buffer.Length - 9, startAbsolutePosition); } catch (ArgumentOutOfRangeException) { break; } Monitor.PulseAll(RecieveBuffer); } Console.WriteLine($"Data got, added:{added}"); if (added) { byte[] message = new byte[1 + 8 + 8]; message[0] = (byte)CommandCode.DataAck; Array.Copy(packet.Buffer, 1, message, 1, 8); byte[] length = BitConverter.GetBytes((long)(packet.Buffer.Length - 9)); Array.Copy(length, 0, message, 1 + 8, 8); await udpclient.SendAsync(message, message.Length, packet.RemoteEndPoint); } else { byte[] message = { (byte)CommandCode.Overloaded }; await udpclient.SendAsync(message, message.Length, packet.RemoteEndPoint); } break; case CommandCode.DataAck: startAbsolutePosition = BitConverter.ToInt64(packet.Buffer, 1); long dataBytesCount = BitConverter.ToInt64(packet.Buffer, 1 + 8); LastRecieved = DateTime.Now; LastSend = DateTime.Now + overloadedPause; // For next data to be sent w/o timeout failedSendAttempts = 0; Console.WriteLine($"Data ack got pos: {startAbsolutePosition} count: {dataBytesCount}"); lock (SendBuffer) { SendBuffer.DisposeElements(startAbsolutePosition, (int)dataBytesCount); Monitor.PulseAll(SendBuffer); } break; case CommandCode.Overloaded: LastRecieved = DateTime.Now; LastSend = DateTime.Now + overloadedPause; // For next data to be sent after pause failedSendAttempts = 0; break; default: throw new ArgumentOutOfRangeException(); } }