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 bool ProcessRecord(int windowSize, int epoch, byte[] buf, int off, int len) { bool checkPreviousFlight = false; while (len >= MessageHeaderLength) { int fragment_length = TlsUtilities.ReadUint24(buf, off + 9); int message_length = fragment_length + MessageHeaderLength; if (len < message_length) { // NOTE: Truncated message - ignore it break; } int length = TlsUtilities.ReadUint24(buf, off + 1); int fragment_offset = TlsUtilities.ReadUint24(buf, off + 6); if (fragment_offset + fragment_length > length) { // NOTE: Malformed fragment - ignore it and the rest of the record break; } /* * NOTE: This very simple epoch check will only work until we want to support * renegotiation (and we're not likely to do that anyway). */ byte msg_type = TlsUtilities.ReadUint8(buf, off + 0); int expectedEpoch = msg_type == HandshakeType.finished ? 1 : 0; if (epoch != expectedEpoch) { break; } int message_seq = TlsUtilities.ReadUint16(buf, off + 4); if (message_seq >= (mNextReceiveSeq + windowSize)) { // NOTE: Too far ahead - ignore } else if (message_seq >= mNextReceiveSeq) { DtlsReassembler reassembler = (DtlsReassembler)mCurrentInboundFlight[message_seq]; if (reassembler == null) { reassembler = new DtlsReassembler(msg_type, length); mCurrentInboundFlight[message_seq] = reassembler; } reassembler.ContributeFragment(msg_type, length, buf, off + MessageHeaderLength, fragment_offset, fragment_length); } else if (mPreviousInboundFlight != null) { /* * NOTE: If we receive the previous flight of incoming messages in full again, * retransmit our last flight */ DtlsReassembler reassembler = (DtlsReassembler)mPreviousInboundFlight[message_seq]; if (reassembler != null) { reassembler.ContributeFragment(msg_type, length, buf, off + MessageHeaderLength, fragment_offset, fragment_length); checkPreviousFlight = true; } } off += message_length; len -= message_length; } bool result = checkPreviousFlight && CheckAll(mPreviousInboundFlight); if (result) { ResendOutboundFlight(); ResetAll(mPreviousInboundFlight); } return(result); }