private Message GetPendingMessage() { DtlsReassembler next = (DtlsReassembler)mCurrentInboundFlight[mNextReceiveSeq]; if (next != null) { byte[] body = next.GetBodyIfComplete(); if (body != null) { mPreviousInboundFlight = null; return(UpdateHandshakeMessagesDigest(new Message(mNextReceiveSeq++, next.MsgType, body))); } } return(null); }
private static bool CheckAll(IDictionary inboundFlight) { global::System.Collections.IEnumerator enumerator = ((global::System.Collections.IEnumerable)inboundFlight.get_Values()).GetEnumerator(); try { while (enumerator.MoveNext()) { DtlsReassembler dtlsReassembler = (DtlsReassembler)enumerator.get_Current(); if (dtlsReassembler.GetBodyIfComplete() == null) { return(false); } } } finally { global::System.IDisposable disposable = enumerator as global::System.IDisposable; if (disposable != null) { disposable.Dispose(); } } return(true); }
internal Message ReceiveMessage() { if (mSending) { mSending = false; PrepareInboundFlight(); } // Check if we already have the next message waiting { DtlsReassembler next = (DtlsReassembler)mCurrentInboundFlight[mNextReceiveSeq]; if (next != null) { byte[] body = next.GetBodyIfComplete(); if (body != null) { mPreviousInboundFlight = null; return(UpdateHandshakeMessagesDigest(new Message(mNextReceiveSeq++, next.MsgType, body))); } } } byte[] buf = null; // TODO Check the conditions under which we should reset this int readTimeoutMillis = 1000; for (;;) { int receiveLimit = mRecordLayer.GetReceiveLimit(); if (buf == null || buf.Length < receiveLimit) { buf = new byte[receiveLimit]; } // TODO Handle records containing multiple handshake messages try { for (; ;) { int received = mRecordLayer.Receive(buf, 0, receiveLimit, readTimeoutMillis); if (received < 0) { break; } if (received < 12) { continue; } int fragment_length = TlsUtilities.ReadUint24(buf, 9); if (received != (fragment_length + 12)) { continue; } int seq = TlsUtilities.ReadUint16(buf, 4); if (seq > (mNextReceiveSeq + MAX_RECEIVE_AHEAD)) { continue; } byte msg_type = TlsUtilities.ReadUint8(buf, 0); int length = TlsUtilities.ReadUint24(buf, 1); int fragment_offset = TlsUtilities.ReadUint24(buf, 6); if (fragment_offset + fragment_length > length) { continue; } if (seq < mNextReceiveSeq) { /* * NOTE: If we Receive the previous flight of incoming messages in full * again, retransmit our last flight */ if (mPreviousInboundFlight != null) { DtlsReassembler reassembler = (DtlsReassembler)mPreviousInboundFlight[seq]; if (reassembler != null) { reassembler.ContributeFragment(msg_type, length, buf, 12, fragment_offset, fragment_length); if (CheckAll(mPreviousInboundFlight)) { ResendOutboundFlight(); /* * TODO[DTLS] implementations SHOULD back off handshake packet * size during the retransmit backoff. */ readTimeoutMillis = System.Math.Min(readTimeoutMillis * 2, 60000); ResetAll(mPreviousInboundFlight); } } } } else { DtlsReassembler reassembler = (DtlsReassembler)mCurrentInboundFlight[seq]; if (reassembler == null) { reassembler = new DtlsReassembler(msg_type, length); mCurrentInboundFlight[seq] = reassembler; } reassembler.ContributeFragment(msg_type, length, buf, 12, fragment_offset, fragment_length); if (seq == mNextReceiveSeq) { byte[] body = reassembler.GetBodyIfComplete(); if (body != null) { mPreviousInboundFlight = null; return(UpdateHandshakeMessagesDigest(new Message(mNextReceiveSeq++, reassembler.MsgType, body))); } } } } } catch (IOException) { // NOTE: Assume this is a timeout for the moment } ResendOutboundFlight(); /* * TODO[DTLS] implementations SHOULD back off handshake packet size during the * retransmit backoff. */ readTimeoutMillis = System.Math.Min(readTimeoutMillis * 2, 60000); } }
internal DtlsReliableHandshake.Message ReceiveMessage() { if (this.mSending) { this.mSending = false; this.PrepareInboundFlight(); } DtlsReassembler dtlsReassembler = (DtlsReassembler)this.mCurrentInboundFlight[this.mNextReceiveSeq]; if (dtlsReassembler != null) { byte[] bodyIfComplete = dtlsReassembler.GetBodyIfComplete(); if (bodyIfComplete != null) { this.mPreviousInboundFlight = null; return(this.UpdateHandshakeMessagesDigest(new DtlsReliableHandshake.Message(this.mNextReceiveSeq++, dtlsReassembler.MsgType, bodyIfComplete))); } } byte[] array = null; int num = 1000; DtlsReliableHandshake.Message result; while (true) { int receiveLimit = this.mRecordLayer.GetReceiveLimit(); if (array != null && array.Length >= receiveLimit) { goto IL_92; } array = new byte[receiveLimit]; try { DtlsReassembler dtlsReassembler3; byte[] bodyIfComplete2; while (true) { IL_92: int num2 = this.mRecordLayer.Receive(array, 0, receiveLimit, num); if (num2 < 0) { goto IL_214; } if (num2 >= 12) { int num3 = TlsUtilities.ReadUint24(array, 9); if (num2 == num3 + 12) { int num4 = TlsUtilities.ReadUint16(array, 4); if (num4 <= this.mNextReceiveSeq + 10) { byte msg_type = TlsUtilities.ReadUint8(array, 0); int num5 = TlsUtilities.ReadUint24(array, 1); int num6 = TlsUtilities.ReadUint24(array, 6); if (num6 + num3 <= num5) { if (num4 < this.mNextReceiveSeq) { if (this.mPreviousInboundFlight != null) { DtlsReassembler dtlsReassembler2 = (DtlsReassembler)this.mPreviousInboundFlight[num4]; if (dtlsReassembler2 != null) { dtlsReassembler2.ContributeFragment(msg_type, num5, array, 12, num6, num3); if (DtlsReliableHandshake.CheckAll(this.mPreviousInboundFlight)) { this.ResendOutboundFlight(); num = Math.Min(num * 2, 60000); DtlsReliableHandshake.ResetAll(this.mPreviousInboundFlight); } } } } else { dtlsReassembler3 = (DtlsReassembler)this.mCurrentInboundFlight[num4]; if (dtlsReassembler3 == null) { dtlsReassembler3 = new DtlsReassembler(msg_type, num5); this.mCurrentInboundFlight[num4] = dtlsReassembler3; } dtlsReassembler3.ContributeFragment(msg_type, num5, array, 12, num6, num3); if (num4 == this.mNextReceiveSeq) { bodyIfComplete2 = dtlsReassembler3.GetBodyIfComplete(); if (bodyIfComplete2 != null) { break; } } } } } } } } this.mPreviousInboundFlight = null; result = this.UpdateHandshakeMessagesDigest(new DtlsReliableHandshake.Message(this.mNextReceiveSeq++, dtlsReassembler3.MsgType, bodyIfComplete2)); break; IL_214 :; } catch (IOException) { } this.ResendOutboundFlight(); num = Math.Min(num * 2, 60000); } return(result); }
internal Message ReceiveMessage() { if (mSending) { mSending = false; PrepareInboundFlight(); } DtlsReassembler dtlsReassembler = (DtlsReassembler)mCurrentInboundFlight.get_Item((object)mNextReceiveSeq); if (dtlsReassembler != null) { byte[] bodyIfComplete = dtlsReassembler.GetBodyIfComplete(); if (bodyIfComplete != null) { mPreviousInboundFlight = null; return(UpdateHandshakeMessagesDigest(new Message(mNextReceiveSeq++, dtlsReassembler.MsgType, bodyIfComplete))); } } byte[] array = null; int num = 1000; while (true) { int receiveLimit = mRecordLayer.GetReceiveLimit(); if (array == null || array.Length < receiveLimit) { array = new byte[receiveLimit]; } try { while (true) { int num2 = mRecordLayer.Receive(array, 0, receiveLimit, num); if (num2 < 0) { break; } if (num2 < 12) { continue; } int num3 = TlsUtilities.ReadUint24(array, 9); if (num2 != num3 + 12) { continue; } int num4 = TlsUtilities.ReadUint16(array, 4); if (num4 > mNextReceiveSeq + 10) { continue; } byte msg_type = TlsUtilities.ReadUint8(array, 0); int num5 = TlsUtilities.ReadUint24(array, 1); int num6 = TlsUtilities.ReadUint24(array, 6); if (num6 + num3 > num5) { continue; } if (num4 < mNextReceiveSeq) { if (mPreviousInboundFlight == null) { continue; } DtlsReassembler dtlsReassembler2 = (DtlsReassembler)mPreviousInboundFlight.get_Item((object)num4); if (dtlsReassembler2 != null) { dtlsReassembler2.ContributeFragment(msg_type, num5, array, 12, num6, num3); if (CheckAll(mPreviousInboundFlight)) { ResendOutboundFlight(); num = Math.Min(num * 2, 60000); ResetAll(mPreviousInboundFlight); } } continue; } DtlsReassembler dtlsReassembler3 = (DtlsReassembler)mCurrentInboundFlight.get_Item((object)num4); if (dtlsReassembler3 == null) { dtlsReassembler3 = new DtlsReassembler(msg_type, num5); mCurrentInboundFlight.set_Item((object)num4, (object)dtlsReassembler3); } dtlsReassembler3.ContributeFragment(msg_type, num5, array, 12, num6, num3); if (num4 == mNextReceiveSeq) { byte[] bodyIfComplete2 = dtlsReassembler3.GetBodyIfComplete(); if (bodyIfComplete2 != null) { mPreviousInboundFlight = null; return(UpdateHandshakeMessagesDigest(new Message(mNextReceiveSeq++, dtlsReassembler3.MsgType, bodyIfComplete2))); } } } } catch (IOException) { } ResendOutboundFlight(); num = Math.Min(num * 2, 60000); } }