示例#1
0
        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);
        }
示例#2
0
        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);
        }