Exemplo n.º 1
0
        /// <summary>
        /// Release resources.
        /// </summary>
        /// <param name = "disposing">
        /// If disposing equals true, Managed and unmanaged resources are disposed. if false, Only unmanaged resources
        /// can be disposed.
        /// </param>
        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                // If disposing equals true, dispose all managed and unmanaged resources.
                if (disposing)
                {
                    // Disconnect with SUT.
                    Disconnect();

                    // Free managed resources & other reference types:
                    if (this.eventQueue != null)
                    {
                        // the SyncFilterQueue may throw exception, donot arise exception.
                        this.eventQueue.Dispose();
                        this.eventQueue = null;
                    }
                    if (this.packetCache != null)
                    {
                        this.packetCache.Dispose();
                        this.packetCache = null;
                    }
                }

                // Call the appropriate methods to clean up unmanaged resources.
                // If disposing is false, only the following code is executed:

                this.disposed = true;
            }
        }
        /// <summary>
        /// expect packet from transport.
        /// </summary>
        /// <param name="buffer">
        /// a BytesBuffer object that contains the received data from endpoint.
        /// </param>
        /// <param name="decoder">
        /// a DecodePacketCallback delegate that is used to decode packet from buffer.
        /// </param>
        /// <param name="endpoint">
        /// an object that specifies the endpoint for decoder.<para/>
        /// remember: this endpoint must be the endpoint that is returned to the user,
        /// that is the endpoint return by Connect().
        /// </param>
        /// <param name="timeout">
        /// a TimeSpan object that indicates the timeout to expect event.
        /// </param>
        /// <param name="packetCache">
        /// a list that contains the stackpackets.
        /// </param>
        /// <returns>
        /// a StackPacket object that specifies the received packet.
        /// </returns>
        public static StackPacket Visit(
            BytesBuffer buffer, DecodePacketCallback decoder, object endpoint,
            TimeSpan timeout, SyncFilterQueue <StackPacket> packetCache)
        {
            // get the packet in packet list.
            if (packetCache.Count > 0)
            {
                return(Utility.GetOne <StackPacket>(packetCache, null));
            }

            // the consumed length of decoder.
            int consumedLength = 0;

            // decode packet, return null or at least one packet.
            StackPacket[] packets = ExpectMultiPacketsVisitor.Visit(
                buffer, decoder, endpoint, timeout, out consumedLength);

            // packet is null, buffer is closed, no packet will come.
            if (packets == null)
            {
                return(null);
            }

            // if packet arrived, add to packet list, and return the first.
            foreach (StackPacket packet in packets)
            {
                packetCache.Enqueue(packet);
            }

            return(Utility.GetOne <StackPacket>(packetCache, null));
        }
Exemplo n.º 3
0
 /// <summary>
 /// enqueue the receivied transport event.<para/>
 /// add the transport event to the event queue, for user to expect specified event directly.<para/>
 /// add the transport event to data sequence, for user to expect any event(include received packet).<para/>
 /// it's thread-safe.
 /// </summary>
 /// <param name="eventQueue">
 /// a SyncFilterQueue&lt;TransportEvent&gt; that specifies the queue to store event.
 /// </param>
 /// <param name="sequence">
 /// a DataSequence object that stores the received data or event sequence.
 /// </param>
 /// <param name="transportEvent">
 /// a TransportEvent object that specifies the received event.
 /// </param>
 public static void Enqueue(SyncFilterQueue <TransportEvent> eventQueue, DataSequence sequence, TransportEvent transportEvent)
 {
     lock (eventQueue)
     {
         sequence.Add(transportEvent, new byte[0], null);
         eventQueue.Enqueue(transportEvent);
     }
 }
Exemplo n.º 4
0
        /// <summary>
        /// dequeue the received event from queue.
        /// </summary>
        /// <param name="eventQueue">
        /// a SyncFilterQueue&lt;TransportEvent&gt; that specifies the queue to store event.
        /// </param>
        /// <param name="sequence">
        /// a DataSequence object that stores the received data or event sequence.
        /// </param>
        /// <param name="timeout">
        /// a TimeSpan object that specifies the timeout to wait for event.
        /// </param>
        /// <param name="filter">
        /// a Filter&lt;TransportEvent&gt; that specifies the filter to get event.
        /// </param>
        /// <returns>
        /// return a TransportEvent object that stores the event.
        /// </returns>
        public static TransportEvent Dequeue(
            SyncFilterQueue <TransportEvent> eventQueue, DataSequence sequence,
            TimeSpan timeout, Filter <TransportEvent> filter)
        {
            TransportEvent transportEvent = eventQueue.Dequeue(timeout, filter);

            // remove the event from sequence.
            sequence.Remove(transportEvent);

            return(transportEvent);
        }
Exemplo n.º 5
0
        /// <summary>
        /// remove the specifies transport event from queue and data sequence.<para/>
        /// invoke this method when get event from the data sequence.
        /// </summary>
        /// <param name="eventQueue">
        /// a SyncFilterQueue&lt;TransportEvent&gt; that specifies the queue to store event.
        /// </param>
        /// <param name="transportEvent">
        /// a TransportEvent object that specifies the event to remove.
        /// </param>
        public static void Remove(
            SyncFilterQueue <TransportEvent> eventQueue, TransportEvent transportEvent)
        {
            lock (eventQueue)
            {
                TransportEvent removedTransportEvent = eventQueue.Dequeue(new TimeSpan());

                if (removedTransportEvent != transportEvent)
                {
                    throw new InvalidOperationException(
                              "the transport event stores in the event queue and data sequence are not consistence.");
                }
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Release resources.
        /// </summary>
        /// <param name = "disposing">
        /// If disposing equals true, Managed and unmanaged resources are disposed. if false, Only unmanaged resources
        /// can be disposed.
        /// </param>
        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                // If disposing equals true, dispose all managed and unmanaged resources.
                if (disposing)
                {
                    // Free managed resources & other reference types:
                    if (this.thread != null)
                    {
                        this.thread.Dispose();
                        this.thread = null;
                    }
                    if (this.transport != null)
                    {
                        // the netbios transport may throw exception, donot arise exception.
                        Utility.SafelyDisconnectNetbiosConnection(this.transport, this.remoteEndPoint);
                        this.transport.Dispose();
                        this.transport = null;
                    }
                    if (this.eventQueue != null)
                    {
                        // the SyncFilterQueue may throw exception, donot arise exception.
                        this.eventQueue.Dispose();
                        this.eventQueue = null;
                    }
                    if (this.packetCache != null)
                    {
                        this.packetCache.Dispose();
                        this.packetCache = null;
                    }
                    if (this.buffer != null)
                    {
                        this.buffer.Dispose();
                        this.buffer = null;
                    }
                }

                // Call the appropriate methods to clean up unmanaged resources.
                // If disposing is false, only the following code is executed:

                this.disposed = true;
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// consturctor.
        /// </summary>
        /// <param name="transportConfig">
        /// a TransportConfig object that contains the config.
        /// </param>
        /// <param name="decodePacketCallback">
        /// a DecodePacketCallback delegate that is used to decode the packet from bytes.
        /// </param>
        /// <exception cref="ArgumentException">
        /// thrown when transportConfig is not StreamConfig
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// thrown when transportConfig is null.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// thrown when decodePacketCallback is null.
        /// </exception>
        public RdpbcgrClientTransportStack(TransportConfig transportConfig, DecodePacketCallback decodePacketCallback)
        {
            if (transportConfig == null)
            {
                throw new ArgumentNullException("transportConfig");
            }

            if (decodePacketCallback == null)
            {
                throw new ArgumentNullException("decodePacketCallback");
            }

            this.UpdateConfig(transportConfig);
            buffer           = new List <byte>();
            this.eventQueue  = new SyncFilterQueue <TransportEvent>();
            this.packetCache = new SyncFilterQueue <StackPacket>();

            this.decoder = decodePacketCallback;
        }
Exemplo n.º 8
0
        /// <summary>
        /// get one packet from packet cache.<para/>
        /// if no packet, return null.
        /// </summary>
        /// <param name="packetCache">
        /// a SyncFilterQueue queue that stores the packet.
        /// </param>
        /// <param name="filter">
        /// the filter to get packet. if null, do not filter packet.
        /// </param>
        /// <returns>
        /// a packet specified by filter.
        /// </returns>
        public static PacketType GetOne <PacketType>(SyncFilterQueue <PacketType> packetCache, Filter <PacketType> filter)
        {
            PacketType packet = default(PacketType);

            if (packetCache.Count == 0)
            {
                return(packet);
            }

            try
            {
                packet = packetCache.Dequeue(new TimeSpan(), filter);
            }
            catch (TimeoutException)
            {
            }

            return(packet);
        }
        /// <summary>
        /// Release resources.
        /// </summary>
        /// <param name = "disposing">
        /// If disposing equals true, Managed and unmanaged resources are disposed. if false, Only unmanaged resources
        /// can be disposed.
        /// </param>
        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                // If disposing equals true, dispose all managed and unmanaged resources.
                if (disposing)
                {
                    // Free managed resources & other reference types:
                    if (this.listeners != null)
                    {
                        // stop listener if exists.
                        if (this.listeners.Count > 0)
                        {
                            this.Stop();
                        }
                        this.listeners = null;
                    }
                    if (this.eventQueue != null)
                    {
                        // the SyncFilterQueue may throw exception, donot arise exception.
                        this.eventQueue.Dispose();
                        this.eventQueue = null;
                    }
                    if (this.packetCache != null)
                    {
                        this.packetCache.Dispose();
                        this.packetCache = null;
                    }
                    if (this.buffer != null)
                    {
                        // the SyncFilterQueue may throw exception, donot arise exception.
                        this.buffer.Dispose();
                        this.buffer = null;
                    }
                }

                // Call the appropriate methods to clean up unmanaged resources.
                // If disposing is false, only the following code is executed:

                this.disposed = true;
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="transportConfig">
        /// a TransportConfig object that contains the config.
        /// </param>
        /// <param name="decodePacketCallback">
        /// a DecodePacketCallback delegate that is used to decode the packet from bytes.
        /// </param>
        /// <exception cref="ArgumentException">
        /// thrown when transportConfig is not SocketTransportConfig
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// thrown when transportConfig is null.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// thrown when decodePacketCallback is null.
        /// </exception>
        public UdpClientTransport(TransportConfig transportConfig, DecodePacketCallback decodePacketCallback)
        {
            if (transportConfig == null)
            {
                throw new ArgumentNullException("transportConfig");
            }

            if (decodePacketCallback == null)
            {
                throw new ArgumentNullException("decodePacketCallback");
            }

            this.UpdateConfig(transportConfig);

            this.eventQueue  = new SyncFilterQueue <TransportEvent>();
            this.buffer      = new SyncFilterQueue <UdpReceivedBytes>();
            this.packetCache = new SyncFilterQueue <IPEndPointStackPacket>();

            this.decoder = decodePacketCallback;
        }
        /// <summary>
        /// consturctor.
        /// </summary>
        /// <param name="transportConfig">
        /// a TransportConfig object that contains the config.
        /// </param>
        /// <param name="decodePacketCallback">
        /// a DecodePacketCallback delegate that is used to decode the packet from bytes.
        /// </param>
        /// <exception cref="ArgumentException">
        /// thrown when transportConfig is not StreamConfig
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// thrown when transportConfig is null.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// thrown when decodePacketCallback is null.
        /// </exception>
        public StreamTransport(TransportConfig transportConfig, DecodePacketCallback decodePacketCallback)
        {
            if (transportConfig == null)
            {
                throw new ArgumentNullException("transportConfig");
            }

            if (decodePacketCallback == null)
            {
                throw new ArgumentNullException("decodePacketCallback");
            }

            this.UpdateConfig(transportConfig);

            this.buffer      = new BytesBuffer();
            this.eventQueue  = new SyncFilterQueue <TransportEvent>();
            this.packetCache = new SyncFilterQueue <StackPacket>();

            this.decoder = decodePacketCallback;
        }
        /// <summary>
        /// SmbdEndpoint constructor will load RDMA providers and initialize default connection values.
        /// </summary>
        /// <param name="inboundEntries">maximum number of outstanding Receive requests.</param>
        /// <param name="outboundEntries">maximum number of outstanding Send, SendAndInvalidate
        /// , Bind, Invalidate, Read, and Write requests.
        /// </param>
        /// <param name="inboundSegment">inbound segments limit</param>
        /// <param name="outboundSegment">outbound segments limit</param>
        /// <param name="inboundReadLimit">maximum inbound read limit for the local Network 
        /// Direct adapter. This value can be zero if you do not support
        /// </param>
        /// <param name="outboundReadLimit"></param>
        /// <param name="inboundDataSize">Max Size of RDMA inbound data</param>
        /// <param name="logEvent">Delegate to log SMBD event</param>
        public SmbdConnectionEndpoint(
            uint inboundEntries,
            uint outboundEntries,
            uint inboundSegment,
            uint outboundSegment,
            uint inboundReadLimit,
            uint outboundReadLimit,
            uint inboundDataSize,
            SmbdLogEvent logEvent = null
            )
        {
            this.logEndpointEvent = logEvent;

            LogEvent("Loading the providers of registered network drivers.");
            initializeStatus = (NtStatus)RdmaProvider.LoadRdmaProviders(out rdmaProvidersList);

            this.inboundEntries = inboundEntries;
            this.outboundEntries = outboundEntries;
            this.inboundSegment = inboundSegment;
            this.outboundSegment = outboundSegment;
            this.inboundReadLimit = inboundReadLimit;
            this.outboundReadLimit = outboundReadLimit;
            this.completionQueueDepth = (inboundEntries + outboundEntries);
            this.inboundDataSize = inboundDataSize;

            isConnected = false;
            memoryWindowList = new List<SmbdMemoryWindow>();
            receiveRequestList = new List<SmbdRequest>();

            locker = new Object();

            otherRequestResult = new SyncFilterQueue<SmbdRequestResult>();
            receiveRequestResult = new SyncFilterQueue<SmbdRequestResult>();

            disconnectSemaphore = new Semaphore(0, 1);
            //threadStopSemaphore = new Semaphore(0, THREAD_COUNT);

            // one more for Semaphore Release when disconnection
            rdmaNotificationSemaphore = new Semaphore(0, (int)completionQueueDepth + 1);
            requestCount = 0;

            ReceivePostedCount = 0;

            #region output provider information
            if (initializeStatus != NtStatus.STATUS_SUCCESS)
            {
                LogEvent(string.Format("Load provider with error code: {0}", (NtStatus)initializeStatus));
                return;
            }
            if (rdmaProvidersList == null)
            {
                LogEvent("The returned providers list is NULL");
                return;
            }

            LogEvent(string.Format("{0} providers of registered network drivers have been load,", rdmaProvidersList.Length));
            int providerIndex = 0;
            foreach (RdmaProviderInfo info in rdmaProvidersList)
            {
                if (info != null)
                {
                    LogEvent(string.Format("Load provider {1}: {0}", info.Path, ++providerIndex));
                }
            }
            LogEvent("Loading providers is completed");
            #endregion
        }
        /// <summary>
        /// consturctor.
        /// </summary>
        /// <param name="transportConfig">
        /// a TransportConfig object that contains the config.
        /// </param>
        /// <param name="decodePacketCallback">
        /// a DecodePacketCallback delegate that is used to decode the packet from bytes.
        /// </param>
        /// <exception cref="ArgumentException">
        /// thrown when transportConfig is not SocketTransportConfig
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// thrown when transportConfig is null.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// thrown when decodePacketCallback is null.
        /// </exception>
        public TcpServerTransport(TransportConfig transportConfig, DecodePacketCallback decodePacketCallback)
        {
            if (transportConfig == null)
            {
                throw new ArgumentNullException("transportConfig");
            }

            if (decodePacketCallback == null)
            {
                throw new ArgumentNullException("decodePacketCallback");
            }

            this.UpdateConfig(transportConfig);

            this.decoder = decodePacketCallback;
            this.listeners = new Dictionary<IPEndPoint, TcpServerListener>();
            this.connections = new Dictionary<IPEndPoint, TcpServerConnection>();
            this.eventQueue = new SyncFilterQueue<TransportEvent>();
            this.sequence = new DataSequence();
            this.packetCache = new SyncFilterQueue<IPEndPointStackPacket>();
        }
        /// <summary>
        /// Release resources. 
        /// </summary>
        /// <param name = "disposing">
        /// If disposing equals true, Managed and unmanaged resources are disposed. if false, Only unmanaged resources 
        /// can be disposed. 
        /// </param>
        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                // If disposing equals true, dispose all managed and unmanaged resources.
                if (disposing)
                {
                    // Free managed resources & other reference types:
                    if (this.listeners != null)
                    {
                        // stop listener if exists.
                        if (this.listeners.Count > 0)
                        {
                            this.Stop();
                        }
                        this.listeners = null;
                    }
                    if (this.connections != null)
                    {
                        // disconnect clients if exists.
                        if (this.connections.Count > 0)
                        {
                            this.Disconnect();
                        }
                        this.connections = null;
                    }
                    if (this.eventQueue != null)
                    {
                        // the SyncFilterQueue may throw exception, donot arise exception.
                        this.eventQueue.Dispose();
                        this.eventQueue = null;
                    }
                    if (this.packetCache != null)
                    {
                        this.packetCache.Dispose();
                        this.packetCache = null;
                    }
                    if (this.sequence != null)
                    {
                        this.sequence.Dispose();
                        this.sequence = null;
                    }
                }

                // Call the appropriate methods to clean up unmanaged resources.
                // If disposing is false, only the following code is executed:

                this.disposed = true;
            }
        }
        /// <summary>
        /// expect packet from transport.<para/>
        /// the transport must be a TcpServer or NetbiosServer.
        /// </summary>
        /// <param name="host">
        /// an IVisitorGetAnyPacket interface that specifies the host of visitor.
        /// </param>
        /// <param name="eventQueue">
        /// a SyncFilterQueue&lt;TransportEvent&gt; that specifies the queue to store event.
        /// </param>
        /// <param name="sequence">
        /// a DataSequence object that manages the sequence information of multiple clients.
        /// </param>
        /// <param name="timeout">
        /// a TimeSpan object that indicates the timeout to expect event.
        /// </param>
        /// <param name="skipEvent">
        /// a bool value that specifies whether skip the event.<para/>
        /// if true, just wait for packet coming; otherwise, both data and event will return.
        /// </param>
        /// <returns>
        /// a StackPacket object that specifies the received packet.<para/>
        /// if all buffer is closed in this while, and required to return if all buffer is closed, return null.<para/>
        /// otherwise never return null, if no packets coming in timespan, throw exception.
        /// </returns>
        public static TransportEvent Visit(
            IVisitorGetAnyData host,
            SyncFilterQueue<TransportEvent> eventQueue, DataSequence sequence, TimeSpan timeout, bool skipEvent)
        {
            // the end time for operation.
            DateTime endTime = DateTime.Now + timeout;
            TimeSpan currentTimeout = timeout;

            while (true)
            {
                sequence.Reset();

                // try to decode packet from all clients in sequence.
                while (true)
                {
                    SequenceItem item = sequence.Next(TimeSpan.MinValue);

                    // all item in the sequences returned
                    if (item == null)
                    {
                        break;
                    }

                    TransportEvent transportEvent = item.Source as TransportEvent;

                    // if event arrived and donot skip the event, return the event directly.
                    if (transportEvent != null)
                    {
                        if (skipEvent)
                        {
                            continue;
                        }

                        sequence.Remove(transportEvent);
                        Utility.Remove(eventQueue, transportEvent);

                        return transportEvent;
                    }

                    object remoteEndPoint;
                    object localEndPoint;

                    host.VisitorGetEndPoint(item.Source, out remoteEndPoint, out localEndPoint);

                    int consumedLength = 0;
                    StackPacket packet = null;

                    try
                    {
                        // set timeout to zero, must not wait for more data.
                        // if timeout, process next.
                        packet = host.VisitorDecodePackets(
                            item.Source, remoteEndPoint, localEndPoint, out consumedLength);

                        // remove the sequence information in data sequence.
                        sequence.Consume(item.Source, consumedLength);

                        if (packet != null)
                        {
                            TcpServerConnection connection = item.Source as TcpServerConnection;

                            if (connection != null)
                            {
                                return connection.VisitorCreateTransportEvent(EventType.ReceivedPacket, packet);
                            }
                            else
                            {
                                return new TransportEvent(EventType.ReceivedPacket, remoteEndPoint, localEndPoint, packet);
                            }
                        }
                    }
                    // skip timeout of any host.
                    catch (TimeoutException)
                    {
                    }
                }

                // waiting for next data coming.
                sequence.Next(currentTimeout);
                currentTimeout = endTime - DateTime.Now;
            }
        }
        /// <summary>
        /// expect packet from transport.<para/>
        /// the transport must be a TcpServer or NetbiosServer.
        /// </summary>
        /// <param name="host">
        /// an IVisitorGetAnyPacket interface that specifies the host of visitor.
        /// </param>
        /// <param name="eventQueue">
        /// a SyncFilterQueue&lt;TransportEvent&gt; that specifies the queue to store event.
        /// </param>
        /// <param name="sequence">
        /// a DataSequence object that manages the sequence information of multiple clients.
        /// </param>
        /// <param name="timeout">
        /// a TimeSpan object that indicates the timeout to expect event.
        /// </param>
        /// <param name="skipEvent">
        /// a bool value that specifies whether skip the event.<para/>
        /// if true, just wait for packet coming; otherwise, both data and event will return.
        /// </param>
        /// <returns>
        /// a StackPacket object that specifies the received packet.<para/>
        /// if all buffer is closed in this while, and required to return if all buffer is closed, return null.<para/>
        /// otherwise never return null, if no packets coming in timespan, throw exception.
        /// </returns>
        public static TransportEvent Visit(
            IVisitorGetAnyData host,
            SyncFilterQueue <TransportEvent> eventQueue, DataSequence sequence, TimeSpan timeout, bool skipEvent)
        {
            // the end time for operation.
            DateTime endTime        = DateTime.Now + timeout;
            TimeSpan currentTimeout = timeout;

            while (true)
            {
                sequence.Reset();

                // try to decode packet from all clients in sequence.
                while (true)
                {
                    SequenceItem item = sequence.Next(TimeSpan.MinValue);

                    // all item in the sequences returned
                    if (item == null)
                    {
                        break;
                    }

                    TransportEvent transportEvent = item.Source as TransportEvent;

                    // if event arrived and donot skip the event, return the event directly.
                    if (transportEvent != null)
                    {
                        if (skipEvent)
                        {
                            continue;
                        }

                        sequence.Remove(transportEvent);
                        Utility.Remove(eventQueue, transportEvent);

                        return(transportEvent);
                    }

                    object remoteEndPoint;
                    object localEndPoint;

                    host.VisitorGetEndPoint(item.Source, out remoteEndPoint, out localEndPoint);

                    int         consumedLength = 0;
                    StackPacket packet         = null;

                    try
                    {
                        // set timeout to zero, must not wait for more data.
                        // if timeout, process next.
                        packet = host.VisitorDecodePackets(
                            item.Source, remoteEndPoint, localEndPoint, out consumedLength);

                        // remove the sequence information in data sequence.
                        sequence.Consume(item.Source, consumedLength);

                        if (packet != null)
                        {
                            TcpServerConnection connection = item.Source as TcpServerConnection;

                            if (connection != null)
                            {
                                return(connection.VisitorCreateTransportEvent(EventType.ReceivedPacket, packet));
                            }
                            else
                            {
                                return(new TransportEvent(EventType.ReceivedPacket, remoteEndPoint, localEndPoint, packet));
                            }
                        }
                    }
                    // skip timeout of any host.
                    catch (TimeoutException)
                    {
                    }
                }

                // waiting for next data coming.
                sequence.Next(currentTimeout);
                currentTimeout = endTime - DateTime.Now;
            }
        }
        /// <summary>
        /// consturctor.
        /// </summary>
        /// <param name="transportConfig">
        /// a TransportConfig object that contains the config.
        /// </param>
        /// <param name="decodePacketCallback">
        /// a DecodePacketCallback delegate that is used to decode the packet from bytes.
        /// </param>
        /// <exception cref="ArgumentException">
        /// thrown when transportConfig is not StreamConfig
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// thrown when transportConfig is null.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// thrown when decodePacketCallback is null.
        /// </exception>
        public StreamTransport(TransportConfig transportConfig, DecodePacketCallback decodePacketCallback)
        {
            if (transportConfig == null)
            {
                throw new ArgumentNullException("transportConfig");
            }

            if (decodePacketCallback == null)
            {
                throw new ArgumentNullException("decodePacketCallback");
            }

            this.UpdateConfig(transportConfig);

            this.buffer = new BytesBuffer();
            this.eventQueue = new SyncFilterQueue<TransportEvent>();
            this.packetCache = new SyncFilterQueue<StackPacket>();

            this.decoder = decodePacketCallback;
        }
        /// <summary>
        /// SmbdEndpoint constructor will load RDMA providers and initialize default connection values.
        /// </summary>
        /// <param name="inboundEntries">maximum number of outstanding Receive requests.</param>
        /// <param name="outboundEntries">maximum number of outstanding Send, SendAndInvalidate
        /// , Bind, Invalidate, Read, and Write requests.
        /// </param>
        /// <param name="inboundSegment">inbound segments limit</param>
        /// <param name="outboundSegment">outbound segments limit</param>
        /// <param name="inboundReadLimit">maximum inbound read limit for the local Network
        /// Direct adapter. This value can be zero if you do not support
        /// </param>
        /// <param name="outboundReadLimit"></param>
        /// <param name="inboundDataSize">Max Size of RDMA inbound data</param>
        /// <param name="logEvent">Delegate to log SMBD event</param>
        public SmbdConnectionEndpoint(
            uint inboundEntries,
            uint outboundEntries,
            uint inboundSegment,
            uint outboundSegment,
            uint inboundReadLimit,
            uint outboundReadLimit,
            uint inboundDataSize,
            SmbdLogEvent logEvent = null
            )
        {
            this.logEndpointEvent = logEvent;

            LogEvent("Loading the providers of registered network drivers.");
            initializeStatus = (NtStatus)RdmaProvider.LoadRdmaProviders(out rdmaProvidersList);

            this.inboundEntries       = inboundEntries;
            this.outboundEntries      = outboundEntries;
            this.inboundSegment       = inboundSegment;
            this.outboundSegment      = outboundSegment;
            this.inboundReadLimit     = inboundReadLimit;
            this.outboundReadLimit    = outboundReadLimit;
            this.completionQueueDepth = (inboundEntries + outboundEntries);
            this.inboundDataSize      = inboundDataSize;

            isConnected        = false;
            memoryWindowList   = new List <SmbdMemoryWindow>();
            receiveRequestList = new List <SmbdRequest>();

            locker = new Object();

            otherRequestResult   = new SyncFilterQueue <SmbdRequestResult>();
            receiveRequestResult = new SyncFilterQueue <SmbdRequestResult>();

            disconnectSemaphore = new Semaphore(0, 1);
            //threadStopSemaphore = new Semaphore(0, THREAD_COUNT);

            // one more for Semaphore Release when disconnection
            rdmaNotificationSemaphore = new Semaphore(0, (int)completionQueueDepth + 1);
            requestCount = 0;

            ReceivePostedCount = 0;

            #region output provider information
            if (initializeStatus != NtStatus.STATUS_SUCCESS)
            {
                LogEvent(string.Format("Load provider with error code: {0}", (NtStatus)initializeStatus));
                return;
            }
            if (rdmaProvidersList == null)
            {
                LogEvent("The returned providers list is NULL");
                return;
            }

            LogEvent(string.Format("{0} providers of registered network drivers have been load,", rdmaProvidersList.Length));
            int providerIndex = 0;
            foreach (RdmaProviderInfo info in rdmaProvidersList)
            {
                if (info != null)
                {
                    LogEvent(string.Format("Load provider {1}: {0}", info.Path, ++providerIndex));
                }
            }
            LogEvent("Loading providers is completed");
            #endregion
        }
        /// <summary>
        /// consturctor.
        /// </summary>
        /// <param name="transportConfig">
        /// a TransportConfig object that contains the config.
        /// </param>
        /// <param name="decodePacketCallback">
        /// a DecodePacketCallback delegate that is used to decode the packet from bytes.
        /// </param>
        /// <exception cref="ArgumentException">
        /// thrown when transportConfig is not StreamConfig
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// thrown when transportConfig is null.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// thrown when decodePacketCallback is null.
        /// </exception>
        public RdpbcgrClientTransportStack(TransportConfig transportConfig, DecodePacketCallback decodePacketCallback)
        {
            if (transportConfig == null)
            {
                throw new ArgumentNullException("transportConfig");
            }

            if (decodePacketCallback == null)
            {
                throw new ArgumentNullException("decodePacketCallback");
            }

            this.UpdateConfig(transportConfig);
            buffer = new List<byte>();
            this.eventQueue = new SyncFilterQueue<TransportEvent>();
            this.packetCache = new SyncFilterQueue<StackPacket>();

            this.decoder = decodePacketCallback;
        }
        /// <summary>
        /// Release resources. 
        /// </summary>
        /// <param name = "disposing">
        /// If disposing equals true, Managed and unmanaged resources are disposed. if false, Only unmanaged resources 
        /// can be disposed. 
        /// </param>
        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                // If disposing equals true, dispose all managed and unmanaged resources.
                if (disposing)
                {
                    // Free managed resources & other reference types:
                    if (this.thread != null)
                    {
                        if(this.thread.IsAlive)
                        {
                            this.thread.Abort();
                            this.thread.Join();
                        }
                        this.thread = null;
                    }
                    if (this.stream != null)
                    {
                        this.stream.Dispose();
                        this.stream = null;
                    }
                    if (this.eventQueue != null)
                    {
                        // the SyncFilterQueue may throw exception, donot arise exception.
                        this.eventQueue.Dispose();
                        this.eventQueue = null;
                    }
                    if (this.packetCache != null)
                    {
                        this.packetCache.Dispose();
                        this.packetCache = null;
                    }
                }

                // Call the appropriate methods to clean up unmanaged resources.
                // If disposing is false, only the following code is executed:

                this.disposed = true;
            }
        }
        /// <summary>
        /// expect packet from transport.
        /// </summary>
        /// <param name="buffer">
        /// a BytesBuffer object that contains the received data from endpoint.
        /// </param>
        /// <param name="decoder">
        /// a DecodePacketCallback delegate that is used to decode packet from buffer.
        /// </param>
        /// <param name="endpoint">
        /// an object that specifies the endpoint for decoder.<para/>
        /// remember: this endpoint must be the endpoint that is returned to the user,
        /// that is the endpoint return by Connect().
        /// </param>
        /// <param name="timeout">
        /// a TimeSpan object that indicates the timeout to expect event.
        /// </param>
        /// <param name="packetCache">
        /// a list that contains the stackpackets.
        /// </param>
        /// <returns>
        /// a StackPacket object that specifies the received packet.
        /// </returns>
        public static StackPacket Visit(
            BytesBuffer buffer, DecodePacketCallback decoder, object endpoint,
            TimeSpan timeout, SyncFilterQueue<StackPacket> packetCache)
        {
            // get the packet in packet list.
            if (packetCache.Count > 0)
            {
                return Utility.GetOne<StackPacket>(packetCache, null);
            }

            // the consumed length of decoder.
            int consumedLength = 0;

            // decode packet, return null or at least one packet.
            StackPacket[] packets = ExpectMultiPacketsVisitor.Visit(
                buffer, decoder, endpoint, timeout, out consumedLength);

            // packet is null, buffer is closed, no packet will come.
            if (packets == null)
            {
                return null;
            }

            // if packet arrived, add to packet list, and return the first.
            foreach (StackPacket packet in packets)
            {
                packetCache.Enqueue(packet);
            }

            return Utility.GetOne<StackPacket>(packetCache, null);
        }
 /// <summary>
 /// Initialize Rpce server.
 /// </summary>
 public RpceServer()
 {
     this.serverContextManager = new RpceContextManager();
     this.receivedTransportEvents = new SyncFilterQueue<RpceTransportEvent>();
 }
        /// <summary>
        /// Release resources. 
        /// </summary>
        /// <param name = "disposing">
        /// If disposing equals true, Managed and unmanaged resources are disposed. if false, Only unmanaged resources 
        /// can be disposed. 
        /// </param>
        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                // If disposing equals true, dispose all managed and unmanaged resources.
                if (disposing)
                {
                    // Free managed resources & other reference types:
                    if (this.thread != null)
                    {
                        this.thread.Dispose();
                        this.thread = null;
                    }
                    if (this.transport != null)
                    {
                        // the netbios transport may throw exception, donot arise exception.
                        Utility.SafelyDisconnectNetbiosConnection(this.transport, this.remoteEndPoint);
                        this.transport.Dispose();
                        this.transport = null;
                    }
                    if (this.eventQueue != null)
                    {
                        // the SyncFilterQueue may throw exception, donot arise exception.
                        this.eventQueue.Dispose();
                        this.eventQueue = null;
                    }
                    if (this.packetCache != null)
                    {
                        this.packetCache.Dispose();
                        this.packetCache = null;
                    }
                    if (this.buffer != null)
                    {
                        this.buffer.Dispose();
                        this.buffer = null;
                    }
                }

                // Call the appropriate methods to clean up unmanaged resources.
                // If disposing is false, only the following code is executed:

                this.disposed = true;
            }
        }
        /// <summary>
        /// Release resources. 
        /// </summary>
        /// <param name = "disposing">
        /// If disposing equals true, Managed and unmanaged resources are disposed. if false, Only unmanaged resources 
        /// can be disposed. 
        /// </param>
        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                // If disposing equals true, dispose all managed and unmanaged resources.
                if (disposing)
                {
                    // Free managed resources & other reference types:
                    // because the client uses listener as transport,
                    // so must stop listener, then dispose client, at last dispose listener.
                    if (this.connections != null)
                    {
                        // stop to accept clients, if exists listener.
                        if (this.listeners.Count > 0)
                        {
                            this.Stop();
                        }
                        // disconnect and dispose all clients, if exists.
                        if (this.connections.Count > 0)
                        {
                            this.Disconnect();
                        }
                        this.connections = null;
                    }
                    // dispose listeners after diposed all clients.
                    if (this.listeners != null)
                    {
                        // dispose all listener if exists.
                        foreach (NetbiosServerListener listener in this.listeners.Values)
                        {
                            listener.Dispose();
                        }
                        this.listeners = null;
                    }
                    if (this.eventQueue != null)
                    {
                        // the SyncFilterQueue may throw exception, donot arise exception.
                        this.eventQueue.Dispose();
                        this.eventQueue = null;
                    }
                    if (this.packetCache != null)
                    {
                        this.packetCache.Dispose();
                        this.packetCache = null;
                    }
                    if (this.sequence != null)
                    {
                        this.sequence.Dispose();
                        this.sequence = null;
                    }
                }

                // Call the appropriate methods to clean up unmanaged resources.
                // If disposing is false, only the following code is executed:

                this.disposed = true;
            }
        }
        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="transportConfig">
        /// a TransportConfig object that contains the config.
        /// </param>
        /// <param name="decodePacketCallback">
        /// a DecodePacketCallback delegate that is used to decode the packet from bytes.
        /// </param>
        /// <exception cref="ArgumentException">
        /// thrown when transportConfig is not SocketTransportConfig
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// thrown when transportConfig is null.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// thrown when decodePacketCallback is null.
        /// </exception>
        public UdpServerTransport(TransportConfig transportConfig, DecodePacketCallback decodePacketCallback)
        {
            if (transportConfig == null)
            {
                throw new ArgumentNullException("transportConfig");
            }

            if (decodePacketCallback == null)
            {
                throw new ArgumentNullException("decodePacketCallback");
            }

            this.UpdateConfig(transportConfig);

            this.listeners = new Dictionary<IPEndPoint, UdpServerListener>();
            this.eventQueue = new SyncFilterQueue<TransportEvent>();
            this.packetCache = new SyncFilterQueue<IPEndPointStackPacket>();
            this.buffer = new SyncFilterQueue<UdpReceivedBytes>();

            this.decoder = decodePacketCallback;
        }