/// <summary>
        /// Create a TcpStreamGenerator given a flow
        /// </summary>
        /// <param name="f">
        /// A <see cref="TcpFlow"/>
        /// </param>
        /// <param name="timeout">
        /// A <see cref="TimeSpan"/>
        /// </param>
        /// <param name="sizeLimitInBytes">
        /// A <see cref="System.Nullable<System.Int64>"/>
        /// </param>
        public TcpStreamGenerator(TcpFlow f,
                                  TimeSpan timeout,
                                  long?sizeLimitInBytes)
        {
            this.flow = f;
            this.flow.OnPacketReceived += HandleFlowOnPacketReceived;
            this.timeout          = timeout;
            this.sizeLimitInBytes = sizeLimitInBytes;

            packets = new LinkedList <PacketDotNet.TcpPacket>();

            tcpStream              = new TcpStream();
            condition              = TcpStreamGenerator.CallbackCondition.NextInSequence;
            waiting_for_start_seq  = true;
            LastContinuousSequence = 0;
            last_overall_seq       = 0;

            // use now as our last packet received time to avoid
            // timing this monitor out immediately
            last_continuous_packet_received = DateTime.Now;
        }
예제 #2
0
        /// <summary>
        /// Return a new TcpStream that is the same as the previous stream but has the packets
        /// we've already read trimmed off of the list
        /// </summary>
        /// <returns>
        /// A <see cref="TcpStream"/>
        /// </returns>
        public TcpStream TrimUnusedPackets()
        {
#if PERFORMANCE_CRITICAL_LOGGING
            log.Debug("");
#endif

            // create a new stream
            TcpStream newStream = new TcpStream();

            // if we have no first packet then we can exit here
            if (FirstPacket == null)
            {
#if PERFORMANCE_CRITICAL_LOGGING
                log.Debug("FirstPacket == null, returning empty TcpStream");
#endif
                return(newStream);
            }

            // copy the first packet variable
            newStream._firstPacket = FirstPacket;

            LinkedListNode <PacketInfo> currentPacket = GetCurrentPosition();

            // special case for when we are at the end of the last packet
            // in which case we have nothing to do
            if (currentPacket == null)
            {
#if PERFORMANCE_CRITICAL_LOGGING
                log.Debug("currentPacket == null, returning empty newStream");
#endif
                return(newStream);
            }

            // the offset of the currentPacket is the number of bytes we can discard
            long bytesToDiscard = currentPacket.Value.offset;

#if PERFORMANCE_CRITICAL_LOGGING
            log.DebugFormat("bytesToDiscard {0}", bytesToDiscard);
#endif

            // copy the PacketInfo entries from the current stream to the new one
            LinkedListNode <PacketInfo> pos = currentPacket;
            while (pos != null)
            {
#if PERFORMANCE_CRITICAL_LOGGING
                log.DebugFormat("adding packet of size {0}", pos.Value.length);
#endif

                // copy the packet info from the current stream
                PacketInfo newPacketInfo = new PacketInfo(pos.Value);

                // adjust its offset
                newPacketInfo.offset -= bytesToDiscard;

                // add it to the new stream
                newStream.packets.AddLast(newPacketInfo);

#if PERFORMANCE_CRITICAL_LOGGING
                log.DebugFormat("newStream.Length {0}", newStream.Length);
#endif

                // advance to the next packet in the current stream
                pos = pos.Next;
            }

#if PERFORMANCE_CRITICAL_LOGGING
            log.DebugFormat("after importing all packets newStream.Length {0}", newStream.Length);
#endif

            // now write the bytes from the old stream
            // NOTE: we cannot use originalBytes.Length because MemoryStream.GetBuffer() returns
            //       the internal buffer that can be larger than the actual number of bytes in the stream
            byte[] originalBytes = base.GetBuffer();
            newStream.Write(originalBytes, (int)bytesToDiscard, (int)(base.Length - bytesToDiscard));

            // set the proper position in the newStream
#if PERFORMANCE_CRITICAL_LOGGING
            log.DebugFormat("base.Position {0}", base.Position);
#endif
            newStream.Position = base.Position - bytesToDiscard;

            //FIXME: for debugging
#if false
            log.DebugFormat("trimmed size from {0} down to {1}, starting packets, {2}, ending packets {3}, removed {4} packets",
                            base.Length, newStream.Length,
                            packets.Count, newStream.packets.Count,
                            (packets.Count - newStream.packets.Count));
            log.DebugFormat("original position of {0} is position of {1} in the newStream",
                            base.Position, newStream.Position);
#endif

            return(newStream);
        }