private void ProcessRecord(SocketAddress address, Session session, DTLSRecord record) { try { #if DEBUG Console.WriteLine(record.RecordType.ToString()); #endif switch (record.RecordType) { case TRecordType.ChangeCipherSpec: if (session != null) { session.ClientEpoch++; session.ClientSequenceNumber = 0; session.SetEncyptChange(record); } break; case TRecordType.Alert: if (session != null) { AlertRecord alertRecord; try { if (session.Cipher == null) { alertRecord = AlertRecord.Deserialise(record.Fragment); } else { long sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; byte[] data = session.Cipher.DecodeCiphertext(sequenceNumber, (byte)TRecordType.Alert, record.Fragment, 0, record.Fragment.Length); alertRecord = AlertRecord.Deserialise(data); } } catch { alertRecord = new AlertRecord(); alertRecord.AlertLevel = TAlertLevel.Fatal; } if (alertRecord.AlertLevel == TAlertLevel.Fatal) { _Sessions.Remove(session, address); } else if ((alertRecord.AlertLevel == TAlertLevel.Warning) || (alertRecord.AlertDescription == TAlertDescription.CloseNotify)) { if (alertRecord.AlertDescription == TAlertDescription.CloseNotify) { SendAlert(session, address, TAlertLevel.Warning, TAlertDescription.CloseNotify); } _Sessions.Remove(session, address); } } break; case TRecordType.Handshake: _Handshake.ProcessHandshake(record); break; case TRecordType.ApplicationData: if (session != null) { if (session.Cipher != null) { long sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; byte[] data = session.Cipher.DecodeCiphertext(sequenceNumber, (byte)TRecordType.ApplicationData, record.Fragment, 0, record.Fragment.Length); if (DataReceived != null) { DataReceived(record.RemoteEndPoint, data); } } } break; default: break; } } #if DEBUG catch (Exception ex) { Console.WriteLine(ex.ToString()); #else catch { #endif SendAlert(session, address, TAlertLevel.Fatal, TAlertDescription.InternalError); } }
private void ProcessRecord(SocketAddress address, Session session, DTLSRecord record) { try { #if DEBUG Console.WriteLine($"> RecordType={record.RecordType.ToString()} sessionID={session?.SessionID} remoteEndPoint={record?.RemoteEndPoint}"); Console.Write($"Data: {TLSUtils.WriteToString(record?.Fragment)}"); #endif switch (record.RecordType) { case TRecordType.ChangeCipherSpec: if (session != null) { session.ClientEpoch++; session.ClientSequenceNumber = 0; session.SetEncyptChange(record); } break; case TRecordType.Alert: if (session != null) { AlertRecord alertRecord; try { if (session.Cipher == null) { alertRecord = AlertRecord.Deserialise(record.Fragment); } else { long sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; byte[] data = session.Cipher.DecodeCiphertext(sequenceNumber, (byte)TRecordType.Alert, record.Fragment, 0, record.Fragment.Length); alertRecord = AlertRecord.Deserialise(data); } } catch { alertRecord = new AlertRecord { AlertLevel = TAlertLevel.Fatal }; } if (alertRecord.AlertLevel == TAlertLevel.Fatal) { _Sessions.Remove(session, address); } else if ((alertRecord.AlertLevel == TAlertLevel.Warning) || (alertRecord.AlertDescription == TAlertDescription.CloseNotify)) { if (alertRecord.AlertDescription == TAlertDescription.CloseNotify) { SendAlert(session, address, TAlertLevel.Warning, TAlertDescription.CloseNotify); } _Sessions.Remove(session, address); } } break; case TRecordType.Handshake: _Handshake.ProcessHandshake(record); break; case TRecordType.ApplicationData: if (session != null) { if (session.Cipher != null) { long sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; byte[] data = session.Cipher.DecodeCiphertext(sequenceNumber, (byte)TRecordType.ApplicationData, record.Fragment, 0, record.Fragment.Length); DataReceived?.Invoke(record.RemoteEndPoint, data); } } break; default: break; } } #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 SendAlert(session, address, TAlertLevel.Fatal, TAlertDescription.InternalError); } }