private void SendChangeCipherSpec() { int size = 1; int responseSize = DTLSRecord.RECORD_OVERHEAD + size; byte[] response = new byte[responseSize]; DTLSRecord record = new DTLSRecord { RecordType = TRecordType.ChangeCipherSpec, Epoch = _Epoch, SequenceNumber = NextSequenceNumber(), Fragment = new byte[size] }; record.Fragment[0] = 1; if (_Version != null) { record.Version = _Version; } using (MemoryStream stream = new MemoryStream(response)) { record.Serialise(stream); } SocketAsyncEventArgs parameters = new SocketAsyncEventArgs() { RemoteEndPoint = _ServerEndPoint }; parameters.SetBuffer(response, 0, responseSize); _Socket.SendToAsync(parameters); ChangeEpoch(); }
private async Task _SendAlertAsync(TAlertLevel alertLevel, TAlertDescription alertDescription, TimeSpan timeout) { if (this._Socket == null) { throw new Exception("Soket Cannot be Null"); } var record = new DTLSRecord { RecordType = TRecordType.Alert, Epoch = _Epoch, SequenceNumber = this._NextSequenceNumber(), Version = this._Version }; var sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; var data = new byte[2]; data[0] = (byte)alertLevel; data[1] = (byte)alertDescription; record.Fragment = this._Cipher == null ? data : this._Cipher.EncodePlaintext(sequenceNumber, (byte)TRecordType.ApplicationData, data, 0, data.Length); var recordSize = DTLSRecord.RECORD_OVERHEAD + record.Fragment.Length; var recordBytes = new byte[recordSize]; using (var stream = new MemoryStream(recordBytes)) { record.Serialise(stream); } await this._Socket.SendAsync(recordBytes, timeout).ConfigureAwait(false); }
private void SendResponseEnd(Session session, IHandshakeMessage handshakeMessage, ushort messageSequence) { int size = handshakeMessage.CalculateSize(session.Version); int maxPayloadSize = _MaxPacketSize - DTLSRecord.RECORD_OVERHEAD + HandshakeRecord.RECORD_OVERHEAD; if (size > maxPayloadSize) { } else { DTLSRecord record = CreateRecord(session, handshakeMessage, messageSequence); session.Handshake.MessageSequence++; DTLSRecord recordEnd = CreateRecord(session, new ServerHelloDone(), session.Handshake.MessageSequence); session.Handshake.MessageSequence++; int responseSize = DTLSRecord.RECORD_OVERHEAD + record.Fragment.Length + DTLSRecord.RECORD_OVERHEAD + recordEnd.Fragment.Length; byte[] response = new byte[responseSize]; using (MemoryStream stream = new MemoryStream(response)) { record.Serialise(stream); recordEnd.Serialise(stream); } SocketAsyncEventArgs parameters = new SocketAsyncEventArgs() { RemoteEndPoint = session.RemoteEndPoint }; parameters.SetBuffer(response, 0, responseSize); _Socket.SendToAsync(parameters); } }
private void SendHandshakeMessage(IHandshakeMessage handshakeMessage, bool encrypt) { int size = handshakeMessage.CalculateSize(_Version); int maxPayloadSize = _MaxPacketSize - DTLSRecord.RECORD_OVERHEAD + HandshakeRecord.RECORD_OVERHEAD; if (size > maxPayloadSize) { } else { DTLSRecord record = new DTLSRecord { RecordType = TRecordType.Handshake, Epoch = _Epoch, SequenceNumber = NextSequenceNumber(), Fragment = new byte[HandshakeRecord.RECORD_OVERHEAD + size] }; if (_Version != null) { record.Version = _Version; } HandshakeRecord handshakeRecord = new HandshakeRecord { MessageType = handshakeMessage.MessageType, MessageSeq = _MessageSequence }; _MessageSequence++; handshakeRecord.Length = (uint)size; handshakeRecord.FragmentLength = (uint)size; using (MemoryStream stream = new MemoryStream(record.Fragment)) { handshakeRecord.Serialise(stream); handshakeMessage.Serialise(stream, _Version); } if (handshakeMessage.MessageType != THandshakeType.HelloVerifyRequest) { _HandshakeInfo.UpdateHandshakeHash(record.Fragment); } int responseSize = DTLSRecord.RECORD_OVERHEAD + HandshakeRecord.RECORD_OVERHEAD + size; if ((_Cipher != null) && encrypt) { long sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; record.Fragment = _Cipher.EncodePlaintext(sequenceNumber, (byte)TRecordType.Handshake, record.Fragment, 0, record.Fragment.Length); responseSize = DTLSRecord.RECORD_OVERHEAD + record.Fragment.Length; } byte[] response = new byte[responseSize]; using (MemoryStream stream = new MemoryStream(response)) { record.Serialise(stream); } SocketAsyncEventArgs parameters = new SocketAsyncEventArgs() { RemoteEndPoint = _ServerEndPoint }; parameters.SetBuffer(response, 0, responseSize); _Socket.SendToAsync(parameters); } }
private void SendResponse(Session session, IHandshakeMessage handshakeMessage, ushort messageSequence) { int size = handshakeMessage.CalculateSize(session.Version); int maxPayloadSize = _MaxPacketSize - DTLSRecord.RECORD_OVERHEAD + HandshakeRecord.RECORD_OVERHEAD; if (size > maxPayloadSize) { } else { DTLSRecord record = new DTLSRecord(); record.RecordType = TRecordType.Handshake; record.Epoch = session.Epoch; record.SequenceNumber = session.NextSequenceNumber(); record.Fragment = new byte[HandshakeRecord.RECORD_OVERHEAD + size]; if (session.Version != null) { record.Version = session.Version; } HandshakeRecord handshakeRecord = new HandshakeRecord(); handshakeRecord.MessageType = handshakeMessage.MessageType; handshakeRecord.MessageSeq = messageSequence; handshakeRecord.Length = (uint)size; handshakeRecord.FragmentLength = (uint)size; using (MemoryStream stream = new MemoryStream(record.Fragment)) { handshakeRecord.Serialise(stream); handshakeMessage.Serialise(stream, session.Version); } if (handshakeMessage.MessageType != THandshakeType.HelloVerifyRequest) { session.Handshake.UpdateHandshakeHash(record.Fragment); } int responseSize = DTLSRecord.RECORD_OVERHEAD + HandshakeRecord.RECORD_OVERHEAD + size; if (session.Cipher != null) { long sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; record.Fragment = session.Cipher.EncodePlaintext(sequenceNumber, (byte)TRecordType.Handshake, record.Fragment, 0, record.Fragment.Length); responseSize = DTLSRecord.RECORD_OVERHEAD + record.Fragment.Length; } byte[] response = new byte[responseSize]; using (MemoryStream stream = new MemoryStream(response)) { record.Serialise(stream); } SocketAsyncEventArgs parameters = new SocketAsyncEventArgs() { RemoteEndPoint = session.RemoteEndPoint }; parameters.SetBuffer(response, 0, responseSize); _Socket.SendToAsync(parameters); } }
public void Send(EndPoint remoteEndPoint, byte[] data) { SocketAddress address = remoteEndPoint.Serialize(); Session session = _Sessions.GetSession(address); if (session != null) { try { DTLSRecord record = new DTLSRecord { RecordType = TRecordType.ApplicationData, Epoch = session.Epoch, SequenceNumber = session.NextSequenceNumber() }; if (session.Version != null) { record.Version = session.Version; } long sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; record.Fragment = session.Cipher.EncodePlaintext(sequenceNumber, (byte)TRecordType.ApplicationData, data, 0, data.Length); int responseSize = DTLSRecord.RECORD_OVERHEAD + record.Fragment.Length; byte[] response = new byte[responseSize]; using (MemoryStream stream = new MemoryStream(response)) { record.Serialise(stream); } SocketAsyncEventArgs parameters = new SocketAsyncEventArgs() { RemoteEndPoint = session.RemoteEndPoint }; parameters.SetBuffer(response, 0, responseSize); _Socket.SendToAsync(parameters); } #if DEBUG catch (Exception ex) { Console.WriteLine(ex.ToString()); StackFrame callStack = new StackFrame(1, true); Console.WriteLine($"Exception! Type: { ex.GetType()}\n\tData: { ex.Data.Count}\n\tMessage: { ex.Message}\n\tSource: { ex.Source}\n\t" + $"StackTrace: { ex.StackTrace}\n\tFile: {callStack.GetFileName()}\n\t" + $"Line: {callStack.GetFileLineNumber()}"); #else catch { #endif } } }
private void SendAlert(Session session, SocketAddress address, TAlertLevel alertLevel, TAlertDescription alertDescription) { #if DEBUG Console.WriteLine($"Alert! {alertDescription}"); #endif if (session != null) { DTLSRecord record = new DTLSRecord { RecordType = TRecordType.Alert, Epoch = session.Epoch, SequenceNumber = session.NextSequenceNumber() }; if (session.Version != null) { record.Version = session.Version; } long sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; byte[] data = new byte[2]; data[0] = (byte)alertLevel; data[1] = (byte)alertDescription; if (session.Cipher == null) { record.Fragment = data; } else { record.Fragment = session.Cipher.EncodePlaintext(sequenceNumber, (byte)TRecordType.ApplicationData, data, 0, data.Length); } int responseSize = DTLSRecord.RECORD_OVERHEAD + record.Fragment.Length; byte[] response = new byte[responseSize]; using (MemoryStream stream = new MemoryStream(response)) { record.Serialise(stream); } SocketAsyncEventArgs parameters = new SocketAsyncEventArgs() { RemoteEndPoint = session.RemoteEndPoint }; parameters.SetBuffer(response, 0, responseSize); _Socket.SendToAsync(parameters); } }
public void Send(EndPoint remoteEndPoint, byte[] data) { SocketAddress address = remoteEndPoint.Serialize(); Session session = _Sessions.GetSession(address); if (session != null) { try { DTLSRecord record = new DTLSRecord(); record.RecordType = TRecordType.ApplicationData; record.Epoch = session.Epoch; record.SequenceNumber = session.NextSequenceNumber(); if (session.Version != null) { record.Version = session.Version; } long sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; record.Fragment = session.Cipher.EncodePlaintext(sequenceNumber, (byte)TRecordType.ApplicationData, data, 0, data.Length); int responseSize = DTLSRecord.RECORD_OVERHEAD + record.Fragment.Length; byte[] response = new byte[responseSize]; using (MemoryStream stream = new MemoryStream(response)) { record.Serialise(stream); } SocketAsyncEventArgs parameters = new SocketAsyncEventArgs() { RemoteEndPoint = session.RemoteEndPoint }; parameters.SetBuffer(response, 0, responseSize); _Socket.SendToAsync(parameters); } #if DEBUG catch (Exception ex) { Console.WriteLine(ex.ToString()); #else catch { #endif } } }
private byte[] _GetChangeCipherSpec() { var size = 1; var responseSize = DTLSRecord.RECORD_OVERHEAD + size; var response = new byte[responseSize]; var record = new DTLSRecord { RecordType = TRecordType.ChangeCipherSpec, Epoch = _Epoch, SequenceNumber = this._NextSequenceNumber(), Fragment = new byte[size], Version = this._Version }; record.Fragment[0] = 1; using (var stream = new MemoryStream(response)) { record.Serialise(stream); } return(response); }
private void SendAlert(TAlertLevel alertLevel, TAlertDescription alertDescription) { DTLSRecord record = new DTLSRecord(); record.RecordType = TRecordType.Alert; record.Epoch = _Epoch; record.SequenceNumber = NextSequenceNumber(); if (_Version != null) { record.Version = _Version; } long sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; byte[] data = new byte[2]; data[0] = (byte)alertLevel; data[1] = (byte)alertDescription; if (_Cipher == null) { record.Fragment = data; } else { record.Fragment = _Cipher.EncodePlaintext(sequenceNumber, (byte)TRecordType.ApplicationData, data, 0, data.Length); } int responseSize = DTLSRecord.RECORD_OVERHEAD + record.Fragment.Length; byte[] response = new byte[responseSize]; using (MemoryStream stream = new MemoryStream(response)) { record.Serialise(stream); } SocketAsyncEventArgs parameters = new SocketAsyncEventArgs() { RemoteEndPoint = _ServerEndPoint }; parameters.SetBuffer(response, 0, responseSize); _Socket.SendToAsync(parameters); }
public async Task SendAsync(byte[] data, TimeSpan timeout) { if (data == null) { throw new ArgumentNullException(nameof(data)); } if (this._Socket == null) { throw new Exception("Socket Cannot be Null"); } if (this._Cipher == null) { throw new Exception("Cipher Cannot be Null"); } var record = new DTLSRecord { RecordType = TRecordType.ApplicationData, Epoch = _Epoch, SequenceNumber = this._NextSequenceNumber(), Version = this._Version }; var sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; record.Fragment = this._Cipher.EncodePlaintext(sequenceNumber, (byte)TRecordType.ApplicationData, data, 0, data.Length); var recordSize = DTLSRecord.RECORD_OVERHEAD + record.Fragment.Length; var recordBytes = new byte[recordSize]; using (var stream = new MemoryStream(recordBytes)) { record.Serialise(stream); } await this._Socket.SendAsync(recordBytes, timeout).ConfigureAwait(false); }
private void SendChangeCipherSpec(Session session) { if (session == null) { throw new ArgumentNullException(nameof(session)); } var size = 1; var responseSize = DTLSRecord.RECORD_OVERHEAD + size; var response = new byte[responseSize]; var record = new DTLSRecord { RecordType = TRecordType.ChangeCipherSpec, Epoch = session.Epoch, SequenceNumber = session.NextSequenceNumber(), Fragment = new byte[size] }; record.Fragment[0] = 1; if (session.Version != null) { record.Version = session.Version; } using (var stream = new MemoryStream(response)) { record.Serialise(stream); } var parameters = new SocketAsyncEventArgs() { RemoteEndPoint = session.RemoteEndPoint }; parameters.SetBuffer(response, 0, responseSize); this._Socket.SendToAsync(parameters); session.ChangeEpoch(); }
private IEnumerable <byte[]> _GetBytes(IHandshakeMessage handshakeMessage, bool encrypt) { if (handshakeMessage == null) { throw new ArgumentNullException(nameof(handshakeMessage)); } var size = handshakeMessage.CalculateSize(this._Version); var maxPayloadSize = _MaxPacketSize - DTLSRecord.RECORD_OVERHEAD + HandshakeRecord.RECORD_OVERHEAD; if (size > maxPayloadSize) { var wholeMessage = new List <byte[]>(); var record = new DTLSRecord { RecordType = TRecordType.Handshake, Epoch = _Epoch, Version = this._Version }; var handshakeRecord = new HandshakeRecord { MessageType = handshakeMessage.MessageType, MessageSeq = _MessageSequence }; if (!(handshakeMessage.MessageType == THandshakeType.HelloVerifyRequest || (handshakeMessage.MessageType == THandshakeType.ClientHello && (handshakeMessage as ClientHello).Cookie == null))) { record.Fragment = new byte[HandshakeRecord.RECORD_OVERHEAD + size]; handshakeRecord.Length = (uint)size; handshakeRecord.FragmentLength = (uint)size; handshakeRecord.FragmentOffset = 0u; using (var stream = new MemoryStream(record.Fragment)) { handshakeRecord.Serialise(stream); handshakeMessage.Serialise(stream, this._Version); } this._HandshakeInfo.UpdateHandshakeHash(record.Fragment); } var dataMessage = new byte[size]; using (var stream = new MemoryStream(dataMessage)) { handshakeMessage.Serialise(stream, this._Version); } var dataMessageFragments = dataMessage.ChunkBySize(maxPayloadSize); handshakeRecord.FragmentOffset = 0U; dataMessageFragments.ForEach(x => { handshakeRecord.Length = (uint)size; handshakeRecord.FragmentLength = (uint)x.Count(); record.SequenceNumber = this._NextSequenceNumber(); var baseMessage = new byte[HandshakeRecord.RECORD_OVERHEAD]; using (var stream = new MemoryStream(baseMessage)) { handshakeRecord.Serialise(stream); } record.Fragment = baseMessage.Concat(x).ToArray(); var responseSize = DTLSRecord.RECORD_OVERHEAD + HandshakeRecord.RECORD_OVERHEAD + x.Count(); if ((this._Cipher != null) && encrypt) { var sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; record.Fragment = this._Cipher.EncodePlaintext(sequenceNumber, (byte)TRecordType.Handshake, record.Fragment, 0, record.Fragment.Length); responseSize = DTLSRecord.RECORD_OVERHEAD + record.Fragment.Length; } var response = new byte[responseSize]; using (var stream = new MemoryStream(response)) { record.Serialise(stream); } wholeMessage.Add(response); handshakeRecord.FragmentOffset += (uint)x.Count(); }); this._MessageSequence++; return(wholeMessage); } else { var record = new DTLSRecord { RecordType = TRecordType.Handshake, Epoch = _Epoch, SequenceNumber = this._NextSequenceNumber(), Fragment = new byte[HandshakeRecord.RECORD_OVERHEAD + size], Version = this._Version }; var handshakeRecord = new HandshakeRecord { MessageType = handshakeMessage.MessageType, MessageSeq = _MessageSequence }; this._MessageSequence++; handshakeRecord.Length = (uint)size; handshakeRecord.FragmentLength = (uint)size; using (var stream = new MemoryStream(record.Fragment)) { handshakeRecord.Serialise(stream); handshakeMessage.Serialise(stream, this._Version); } if (!(handshakeMessage.MessageType == THandshakeType.HelloVerifyRequest || (handshakeMessage.MessageType == THandshakeType.ClientHello && (handshakeMessage as ClientHello).Cookie == null))) { this._HandshakeInfo.UpdateHandshakeHash(record.Fragment); } var responseSize = DTLSRecord.RECORD_OVERHEAD + HandshakeRecord.RECORD_OVERHEAD + size; if ((this._Cipher != null) && encrypt) { var sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; record.Fragment = this._Cipher.EncodePlaintext(sequenceNumber, (byte)TRecordType.Handshake, record.Fragment, 0, record.Fragment.Length); responseSize = DTLSRecord.RECORD_OVERHEAD + record.Fragment.Length; } var response = new byte[responseSize]; using (var stream = new MemoryStream(response)) { record.Serialise(stream); } return(new List <byte[]>() { response }); } }
private void SendChangeCipherSpec(Session session) { int size = 1; int responseSize = DTLSRecord.RECORD_OVERHEAD + size; byte[] response = new byte[responseSize]; DTLSRecord record = new DTLSRecord(); record.RecordType = TRecordType.ChangeCipherSpec; record.Epoch = session.Epoch; record.SequenceNumber = session.NextSequenceNumber(); record.Fragment = new byte[size]; record.Fragment[0] = 1; if (session.Version != null) record.Version = session.Version; using (MemoryStream stream = new MemoryStream(response)) { record.Serialise(stream); } SocketAsyncEventArgs parameters = new SocketAsyncEventArgs() { RemoteEndPoint = session.RemoteEndPoint }; parameters.SetBuffer(response, 0, responseSize); _Socket.SendToAsync(parameters); session.ChangeEpoch(); }
private void SendAlert(TAlertLevel alertLevel, TAlertDescription alertDescription) { DTLSRecord record = new DTLSRecord(); record.RecordType = TRecordType.Alert; record.Epoch = _Epoch; record.SequenceNumber = NextSequenceNumber(); if (_Version != null) record.Version = _Version; long sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; byte[] data = new byte[2]; data[0] = (byte)alertLevel; data[1] = (byte)alertDescription; if (_Cipher == null) record.Fragment = data; else record.Fragment = _Cipher.EncodePlaintext(sequenceNumber, (byte)TRecordType.ApplicationData, data, 0, data.Length); int responseSize = DTLSRecord.RECORD_OVERHEAD + record.Fragment.Length; byte[] response = new byte[responseSize]; using (MemoryStream stream = new MemoryStream(response)) { record.Serialise(stream); } SocketAsyncEventArgs parameters = new SocketAsyncEventArgs() { RemoteEndPoint = _ServerEndPoint }; parameters.SetBuffer(response, 0, responseSize); _Socket.SendToAsync(parameters); }
public void Send(byte[] data) { try { DTLSRecord record = new DTLSRecord(); record.RecordType = TRecordType.ApplicationData; record.Epoch = _Epoch; record.SequenceNumber = NextSequenceNumber(); if (_Version != null) record.Version = _Version; long sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; record.Fragment = _Cipher.EncodePlaintext(sequenceNumber, (byte)TRecordType.ApplicationData, data, 0, data.Length); int responseSize = DTLSRecord.RECORD_OVERHEAD + record.Fragment.Length; byte[] response = new byte[responseSize]; using (MemoryStream stream = new MemoryStream(response)) { record.Serialise(stream); } SocketAsyncEventArgs parameters = new SocketAsyncEventArgs() { RemoteEndPoint = _ServerEndPoint }; parameters.SetBuffer(response, 0, responseSize); if (_Socket != null) _Socket.SendToAsync(parameters); } #if DEBUG catch (Exception ex) { Console.WriteLine(ex.ToString()); #else catch { #endif } }
private void SendResponse(Session session, IHandshakeMessage handshakeMessage, ushort messageSequence) { int size = handshakeMessage.CalculateSize(session.Version); int maxPayloadSize = _MaxPacketSize - DTLSRecord.RECORD_OVERHEAD + HandshakeRecord.RECORD_OVERHEAD; if (size > maxPayloadSize) { } else { DTLSRecord record = new DTLSRecord(); record.RecordType = TRecordType.Handshake; record.Epoch = session.Epoch; record.SequenceNumber = session.NextSequenceNumber(); record.Fragment = new byte[HandshakeRecord.RECORD_OVERHEAD + size]; if (session.Version != null) record.Version = session.Version; HandshakeRecord handshakeRecord = new HandshakeRecord(); handshakeRecord.MessageType = handshakeMessage.MessageType; handshakeRecord.MessageSeq = messageSequence; handshakeRecord.Length = (uint)size; handshakeRecord.FragmentLength = (uint)size; using (MemoryStream stream = new MemoryStream(record.Fragment)) { handshakeRecord.Serialise(stream); handshakeMessage.Serialise(stream, session.Version); } if (handshakeMessage.MessageType != THandshakeType.HelloVerifyRequest) { session.Handshake.UpdateHandshakeHash(record.Fragment); } int responseSize = DTLSRecord.RECORD_OVERHEAD + HandshakeRecord.RECORD_OVERHEAD + size; if (session.Cipher != null) { long sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; record.Fragment = session.Cipher.EncodePlaintext(sequenceNumber, (byte)TRecordType.Handshake, record.Fragment, 0, record.Fragment.Length); responseSize = DTLSRecord.RECORD_OVERHEAD + record.Fragment.Length; } byte[] response = new byte[responseSize]; using (MemoryStream stream = new MemoryStream(response)) { record.Serialise(stream); } SocketAsyncEventArgs parameters = new SocketAsyncEventArgs() { RemoteEndPoint = session.RemoteEndPoint }; parameters.SetBuffer(response, 0, responseSize); _Socket.SendToAsync(parameters); } }
private void SendResponse(Session session, IHandshakeMessage handshakeMessage, ushort messageSequence) { if (session == null) { throw new ArgumentNullException(nameof(session)); } if (handshakeMessage == null) { throw new ArgumentNullException(nameof(handshakeMessage)); } var size = handshakeMessage.CalculateSize(session.Version); var maxPayloadSize = this._MaxPacketSize - DTLSRecord.RECORD_OVERHEAD + HandshakeRecord.RECORD_OVERHEAD; if (size > maxPayloadSize) { //fragments return; } var record = new DTLSRecord { RecordType = TRecordType.Handshake, Epoch = session.Epoch, SequenceNumber = session.NextSequenceNumber(), Fragment = new byte[HandshakeRecord.RECORD_OVERHEAD + size] }; if (session.Version != null) { record.Version = session.Version; } var handshakeRecord = new HandshakeRecord { MessageType = handshakeMessage.MessageType, MessageSeq = messageSequence, Length = (uint)size, FragmentLength = (uint)size }; using (var stream = new MemoryStream(record.Fragment)) { handshakeRecord.Serialise(stream); handshakeMessage.Serialise(stream, session.Version); } if (handshakeMessage.MessageType != THandshakeType.HelloVerifyRequest) { session.Handshake.UpdateHandshakeHash(record.Fragment); } var responseSize = DTLSRecord.RECORD_OVERHEAD + HandshakeRecord.RECORD_OVERHEAD + size; if (session.Cipher != null) { var sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; record.Fragment = session.Cipher.EncodePlaintext(sequenceNumber, (byte)TRecordType.Handshake, record.Fragment, 0, record.Fragment.Length); responseSize = DTLSRecord.RECORD_OVERHEAD + record.Fragment.Length; } var response = new byte[responseSize]; using (var stream = new MemoryStream(response)) { record.Serialise(stream); } var parameters = new SocketAsyncEventArgs() { RemoteEndPoint = session.RemoteEndPoint }; parameters.SetBuffer(response, 0, responseSize); this._Socket.SendToAsync(parameters); }