private void ProcessAndPush(PacketBuffer Buffer, MemoryStream PacketStream) { int hdrLen = DtmPacketStruct.GetHeaderSize(); int pktLen = 0; // get the header DtmPacketStruct pktHdr = new DtmPacketStruct(PacketStream); PacketStream.Seek(0, SeekOrigin.Begin); // track high sequence number if (pktHdr.Sequence > _seqCounter) { _seqCounter = pktHdr.Sequence; } // out of sync, possible packet loss if (_seqCounter - _rcvSequence > _bufferCount / 4) { // request a retransmission Transmit(DtmPacketFlags.Service, (short)DtmServiceFlags.Resend, _rcvSequence + 1); } // packet aligned if (pktHdr.PayloadLength + hdrLen == PacketStream.Length) { // resend was already processed if (pktHdr.Sequence < _rcvSequence) { return; } // push onto buffer Buffer.Push(pktHdr.Sequence, PacketStream); } // more than one packet else if (pktHdr.PayloadLength + hdrLen < PacketStream.Length) { byte[] buffer; long pos = 0; do { // get packet position and size pos = PacketStream.Position; if (PacketStream.Length - pos < DtmPacketStruct.GetHeaderSize()) { // next packet corrupted, request a retransmission and exit Transmit(DtmPacketFlags.Service, (short)DtmServiceFlags.Resend, Buffer.GetHighKey() + 1); return; } pktHdr = new DtmPacketStruct(PacketStream); pktLen = (int)(hdrLen + pktHdr.PayloadLength); if (pktLen > MAXRCVBUFFER || pktLen < 0 || PacketStream.Length - pos < pktLen) { // packet corrupted, request a retransmission and exit Transmit(DtmPacketFlags.Service, (short)DtmServiceFlags.Resend, Buffer.GetHighKey() + 1); return; } else { // create the buffer buffer = new byte[pktLen]; PacketStream.Seek(pos, SeekOrigin.Begin); PacketStream.Read(buffer, 0, (int)pktLen); // push onto buffer Buffer.Push(pktHdr.Sequence, new MemoryStream(buffer)); } } while (PacketStream.Position < PacketStream.Length); } // malformed packet, send retransmit request else if (pktHdr.PayloadLength > MAXRCVBUFFER || pktHdr.PayloadLength < 0 || pktHdr.PayloadLength + hdrLen > PacketStream.Length) { // packet corrupted, request a retransmission of last in queue + 1 Transmit(DtmPacketFlags.Service, (short)DtmServiceFlags.Resend, Buffer.GetHighKey() + 1); } }