예제 #1
0
 /// <summary>
 /// Initialize the channel.
 /// </summary>
 /// <param name="manager"></param>
 /// <param name="channelid"></param>
 /// <param name="context"></param>
 protected internal virtual void Init(SSHPacketRouter manager, int channelid, SSHContext context)
 {
     this.channelid = channelid;
     this.manager   = manager;
     this.ms        = new SSHPacketStore(manager, this, "Channel " + channelid);
     this.context   = context;
     FireEvent(this, ChannelState.INITIALIZED);
 }
예제 #2
0
 /// <summary>
 /// Create a router
 /// </summary>
 /// <param name="reader"></param>
 /// <param name="maxChannels"></param>
 /// <param name="buffered"></param>
 public SSHPacketRouter(SSHPacketReader reader, int maxChannels, bool buffered)
 {
     this.reader   = reader;
     this.channels = new SSHAbstractChannel[maxChannels];
     this.global   = new SSHPacketStore(this, null, "Global");
     this.sync     = new ThreadSynchronizer(buffered);
     this.buffered = buffered;
 }
예제 #3
0
        /// <summary>
        /// Get the next message from the <see cref="Maverick.SSH.Packets.SSHPacketRouter"/> that matches one of the
        /// ids supplied in the message filter and return its index in the channels message store.
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="observer"></param>
        /// <returns></returns>
        protected internal SSHPacket NextMessage(SSHAbstractChannel channel, PacketObserver observer)
        {
            SSHPacketStore store = channel == null? global : channel.MessageStore;

            PacketHolder holder = new PacketHolder();

            while (!store.Closed && holder.msg == null)
            {
                // Check for an error from the buffering thread
                if (buffered)
                {
                    if (!isClosing)
                    {
                        if (lastError != null)
                        {
                            if (lastError is SSHException)
                            {
                                throw lastError;
                            }
                            else
                            {
                                throw new SSHException(lastError);
                            }
                        }
                    }
                }


                if (sync.RequestBlock(store, observer, holder))
                {
                    try
                    {
                        BlockForMessage();
                    }
                    finally
                    {
                        // Release the block so that other threads may block or return with the
                        // newly arrived message
                        sync.ReleaseBlock();
                    }
                }
            }

            return(holder.msg);
        }
예제 #4
0
        /// <summary>
        /// Request to obtain the real block but check for messages first in the packet store.
        /// </summary>
        /// <param name="store"></param>
        /// <param name="observer"></param>
        /// <param name="holder"></param>
        /// <returns></returns>
        public bool RequestBlock(SSHPacketStore store, PacketObserver observer, PacketHolder holder)
        {
            lock (this)
            {
//#if DEBUG
//				System.Diagnostics.Trace.WriteLine(System.Threading.Thread.CurrentThread.Name + ": Obtained lock on sync");
//#endif

                if ((holder.msg = store.HasMessage(observer)) != null)
                {
//#if DEBUG
//					System.Diagnostics.Trace.WriteLine(System.Threading.Thread.CurrentThread.Name + ": w00t I've found a message");
//#endif
                    return(false);
                }


                bool canBlock = !isBlocking;

                if (canBlock)
                {
//#if DEBUG
//					System.Diagnostics.Trace.WriteLine(System.Threading.Thread.CurrentThread.Name + ": w00t I've got the *real* block");
//#endif
                    isBlocking = true;
                }
                else
                {
//#if DEBUG
//					System.Diagnostics.Trace.WriteLine(System.Threading.Thread.CurrentThread.Name + ": :( Waiting on sync in pseudo block");
//#endif

                    System.Threading.Monitor.Wait(this);
                }

//#if DEBUG
//				System.Diagnostics.Trace.WriteLine(System.Threading.Thread.CurrentThread.Name + ": Exiting RequestBlock");
//#endif
                return(canBlock);
            }
        }
예제 #5
0
        private bool BlockForMessage()
        {
            SSHPacket packet = reader.NextMessage();

#if DEBUG
            System.Diagnostics.Trace.WriteLine("Received message id " + packet.MessageID);
#endif

            if (IsChannelMessage(packet.MessageID))
            {
                packet = new SSHChannelMessage(packet);
            }


            // Determine the destination channel (if any)
            SSHAbstractChannel destination = null;
            if (packet is SSHChannelMessage)
            {
                destination = channels[((SSHChannelMessage)packet).ChannelID];
            }

            // Call the destination so that they may process the message
            bool processed = destination == null
                                ? ProcessGlobalMessage(packet)
                                : destination.ProcessChannelMessage((SSHChannelMessage)packet);

            // If the previous call did not process the message then add to the
            // destinations message store
            if (!processed)
            {
                SSHPacketStore ms = destination == null? global : destination.MessageStore;
//#if DEBUG
//						System.Diagnostics.Trace.WriteLine("Adding message " + packet.MessageID + " to store " + ms.ToString() );
//#endif

                ms.AddMessage(packet);
            }


            return(!processed);
        }