From a322c96a1c434ffffe445a1ac4be4e9158c30fb8 Mon Sep 17 00:00:00 2001 From: olegkap_cp Date: Fri, 5 Nov 2010 20:42:49 +0000 Subject: [PATCH] Refactor channel message handling by converting into events --- .../Renci.SshClient.Tests/ShellTest.cs | 11 +- .../ChannelOpeningEventArgs.cs | 11 - .../Renci.SshClient/Channels/Channel.cs | 184 ++++++++++------ .../Channels/ChannelDirectTcpip.cs | 17 +- .../Channels/ChannelForwardedTcpip.cs | 4 +- .../Channels/ChannelSession.cs | 32 +-- .../Channels/ChannelSessionExec.cs | 27 +-- .../Channels/ChannelSessionSftp.cs | 8 +- .../Renci.SshClient/ForwardedPortRemote.cs | 12 +- .../Renci.SshClient/MessageEventArgs.cs | 14 ++ .../Renci.SshClient/Renci.SshClient.csproj | 3 +- .../RequestSuccessEventArgs.cs | 9 - Renci.SshClient/Renci.SshClient/Session.cs | 198 ++++++++++++++---- 13 files changed, 342 insertions(+), 188 deletions(-) delete mode 100644 Renci.SshClient/Renci.SshClient/ChannelOpeningEventArgs.cs create mode 100644 Renci.SshClient/Renci.SshClient/MessageEventArgs.cs delete mode 100644 Renci.SshClient/Renci.SshClient/RequestSuccessEventArgs.cs diff --git a/Renci.SshClient/Renci.SshClient.Tests/ShellTest.cs b/Renci.SshClient/Renci.SshClient.Tests/ShellTest.cs index 076147c1..41d52069 100644 --- a/Renci.SshClient/Renci.SshClient.Tests/ShellTest.cs +++ b/Renci.SshClient/Renci.SshClient.Tests/ShellTest.cs @@ -100,24 +100,18 @@ namespace Renci.SshClient.Tests [TestMethod] public void TestMultipleThreadMultipleSessions_10000() { - // TODO: Restore test to 10000 items var s = CreateShellUsingPassword(); s.Connect(); - var numOfLoops = 100000; - var exeCounter = 0; - System.Threading.Tasks.Parallel.For(0, numOfLoops, + System.Threading.Tasks.Parallel.For(0, 10000, (counter) => { var result = ExecuteTestCommand(s); Debug.WriteLine(string.Format("TestMultipleThreadMultipleConnections #{0}", counter)); - exeCounter++; Assert.IsTrue(result); } ); s.Disconnect(); - - Assert.AreEqual(exeCounter, numOfLoops); } [TestMethod] @@ -125,8 +119,7 @@ namespace Renci.SshClient.Tests { try { - // TODO: Restore test to 10000 items - System.Threading.Tasks.Parallel.For(0, 100, + System.Threading.Tasks.Parallel.For(0, 10000, () => { var s = CreateShellUsingPassword(); diff --git a/Renci.SshClient/Renci.SshClient/ChannelOpeningEventArgs.cs b/Renci.SshClient/Renci.SshClient/ChannelOpeningEventArgs.cs deleted file mode 100644 index 765ff52e..00000000 --- a/Renci.SshClient/Renci.SshClient/ChannelOpeningEventArgs.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using Renci.SshClient.Messages.Connection; - -namespace Renci.SshClient -{ - internal class ChannelOpeningEventArgs : EventArgs - { - public ChannelOpenMessage Message { get; set; } - - } -} diff --git a/Renci.SshClient/Renci.SshClient/Channels/Channel.cs b/Renci.SshClient/Renci.SshClient/Channels/Channel.cs index 73208f7c..c09789b3 100644 --- a/Renci.SshClient/Renci.SshClient/Channels/Channel.cs +++ b/Renci.SshClient/Renci.SshClient/Channels/Channel.cs @@ -62,6 +62,18 @@ namespace Renci.SshClient.Channels this.Session.RegisterMessageType(MessageTypes.ChannelEof); this.Session.RegisterMessageType(MessageTypes.ChannelClose); + this.Session.ChannelOpen += OnChannelOpen; + this.Session.ChannelOpenConfirmation += OnChannelOpenConfirmation; + this.Session.ChannelOpenFailure += OnChannelOpenFailure; + this.Session.ChannelWindowAdjust += OnChannelWindowAdjust; + this.Session.ChannelData += OnChannelData; + this.Session.ChannelExtendedData += OnChannelExtendedData; + this.Session.ChannelEof += OnChannelEof; + this.Session.ChannelClose += OnChannelClose; + this.Session.ChannelRequest += OnChannelRequest; + this.Session.ChannelSuccess += OnChannelSuccess; + this.Session.ChannelFailure += OnChannelFailure; + } public virtual void Close() @@ -77,42 +89,65 @@ namespace Renci.SshClient.Channels this.CloseCleanup(); } - internal void HandleChannelMessage(ChannelMessage message) - { - this.HandleMessage((dynamic)message); - } + #region Channel virtual methods - protected virtual void OnChannelData(string data) + protected virtual void OnOpen(ChannelTypes channelTypes, uint initialWindowSize, uint maximumPacketSize, string connectedAddress, uint connectedPort, string originatorAddress, uint originatorPort) { } - protected virtual void OnChannelExtendedData(string data, uint dataTypeCode) + protected virtual void OnOpenConfirmation(uint remoteChannelNumber, uint initialWindowSize, uint maximumPacketSize) + { + this.RemoteChannelNumber = remoteChannelNumber; + this.ServerWindowSize = initialWindowSize; + this.PacketSize = maximumPacketSize; + + this.IsOpen = true; + } + + protected virtual void OnOpenFailure(uint reasonCode, string description, string language) { } - protected virtual void OnChannelSuccess() + protected virtual void OnWindowAdjust(uint bytesToAdd) + { + this.ServerWindowSize += bytesToAdd; + this._channelWindowAdjustWaitHandle.Set(); + } + + protected virtual void OnData(string data) + { + this.AdjustDataWindow(data); + } + + protected virtual void OnExtendedData(string data, uint dataTypeCode) + { + this.AdjustDataWindow(data); + } + + protected virtual void OnEof() { } - protected virtual void OnChannelEof() + protected virtual void OnClose() + { + this.CloseCleanup(); + + this._channelClosedWaitHandle.Set(); + } + + protected virtual void OnRequest(ChannelRequestNames requestName, bool wantReply, string command, string subsystemName, uint exitStatus) { } - protected virtual void OnChannelOpen() + protected virtual void OnSuccess() { } - protected virtual void OnChannelClose() + protected virtual void OnFailure() { } - protected virtual void OnChannelRequest(ChannelRequestMessage message) - { - } - - protected virtual void OnChannelFailed(uint reasonCode, string description) - { - } + #endregion protected void SendMessage(Message message) { @@ -143,69 +178,109 @@ namespace Renci.SshClient.Channels this.Session.SendMessage(message); } - #region Message handlers - - private void HandleMessage(T message) where T : Message + protected void CloseCleanup() { - throw new NotSupportedException(string.Format("Message type '{0}' is not supported.", message.MessageType)); + if (!this.IsOpen) + return; + + this.IsOpen = false; + this.SendChannelCloseMessage(); } - private void HandleMessage(ChannelOpenConfirmationMessage message) + #region Channel message event handlers + + private void OnChannelOpen(object sender, MessageEventArgs e) { - this.RemoteChannelNumber = message.RemoteChannelNumber; - this.ServerWindowSize = message.InitialWindowSize; - this.PacketSize = message.MaximumPacketSize; - - this.IsOpen = true; - - this.OnChannelOpen(); + if (e.Message.LocalChannelNumber == this.LocalChannelNumber) + { + this.OnOpen(e.Message.ChannelType, e.Message.InitialWindowSize, e.Message.MaximumPacketSize, e.Message.ConnectedAddress, e.Message.ConnectedPort, e.Message.OriginatorAddress, e.Message.OriginatorPort); + } } - private void HandleMessage(ChannelOpenFailureMessage message) + private void OnChannelOpenConfirmation(object sender, MessageEventArgs e) { - this.OnChannelFailed(message.ReasonCode, message.Description); + if (e.Message.LocalChannelNumber == this.LocalChannelNumber) + { + this.OnOpenConfirmation(e.Message.RemoteChannelNumber, e.Message.InitialWindowSize, e.Message.MaximumPacketSize); + } } - private void HandleMessage(ChannelWindowAdjustMessage message) + private void OnChannelOpenFailure(object sender, MessageEventArgs e) { - this.ServerWindowSize += message.BytesToAdd; - this._channelWindowAdjustWaitHandle.Set(); + if (e.Message.LocalChannelNumber == this.LocalChannelNumber) + { + this.OnOpenFailure(e.Message.ReasonCode, e.Message.Description, e.Message.Language); + } } - private void HandleMessage(ChannelDataMessage message) + private void OnChannelWindowAdjust(object sender, MessageEventArgs e) { - this.AdjustDataWindow(message.Data); - this.OnChannelData(message.Data); + if (e.Message.LocalChannelNumber == this.LocalChannelNumber) + { + this.OnWindowAdjust(e.Message.BytesToAdd); + } } - private void HandleMessage(ChannelExtendedDataMessage message) + private void OnChannelData(object sender, MessageEventArgs e) { - this.AdjustDataWindow(message.Data); - this.OnChannelExtendedData(message.Data, message.DataTypeCode); + if (e.Message.LocalChannelNumber == this.LocalChannelNumber) + { + this.OnData(e.Message.Data); + } } - private void HandleMessage(ChannelRequestMessage message) + private void OnChannelExtendedData(object sender, MessageEventArgs e) { - this.OnChannelRequest(message); + if (e.Message.LocalChannelNumber == this.LocalChannelNumber) + { + this.OnExtendedData(e.Message.Data, e.Message.DataTypeCode); + } } - private void HandleMessage(ChannelSuccessMessage message) + private void OnChannelEof(object sender, MessageEventArgs e) { - this.OnChannelSuccess(); + if (e.Message.LocalChannelNumber == this.LocalChannelNumber) + { + this.OnEof(); + } } - private void HandleMessage(ChannelEofMessage message) + private void OnChannelClose(object sender, MessageEventArgs e) { - this.OnChannelEof(); + if (e.Message.LocalChannelNumber == this.LocalChannelNumber) + { + this.OnClose(); + + //// TODO: Refactor so this could will not be here + //this.CloseCleanup(); + + //this._channelClosedWaitHandle.Set(); + + } } - private void HandleMessage(ChannelCloseMessage message) + private void OnChannelRequest(object sender, MessageEventArgs e) { - this.OnChannelClose(); + if (e.Message.LocalChannelNumber == this.LocalChannelNumber) + { + this.OnRequest(e.Message.RequestName, e.Message.WantReply, e.Message.Command, e.Message.SubsystemName, e.Message.ExitStatus); + } + } - this.CloseCleanup(); + private void OnChannelSuccess(object sender, MessageEventArgs e) + { + if (e.Message.LocalChannelNumber == this.LocalChannelNumber) + { + this.OnSuccess(); + } + } - this._channelClosedWaitHandle.Set(); + private void OnChannelFailure(object sender, MessageEventArgs e) + { + if (e.Message.LocalChannelNumber == this.LocalChannelNumber) + { + this.OnFailure(); + } } #endregion @@ -244,15 +319,6 @@ namespace Renci.SshClient.Channels } } - protected void CloseCleanup() - { - if (!this.IsOpen) - return; - - this.IsOpen = false; - this.SendChannelCloseMessage(); - } - #region IDisposable Members protected abstract void OnDisposing(); diff --git a/Renci.SshClient/Renci.SshClient/Channels/ChannelDirectTcpip.cs b/Renci.SshClient/Renci.SshClient/Channels/ChannelDirectTcpip.cs index 7a8174da..2517838b 100644 --- a/Renci.SshClient/Renci.SshClient/Channels/ChannelDirectTcpip.cs +++ b/Renci.SshClient/Renci.SshClient/Channels/ChannelDirectTcpip.cs @@ -120,32 +120,27 @@ namespace Renci.SshClient.Channels readerTask.Wait(); } - protected override void OnChannelData(string data) + protected override void OnData(string data) { - base.OnChannelData(data); + base.OnData(data); this._socket.Send(data.GetSshBytes().ToArray(), 0, data.Length, SocketFlags.None); } - protected override void OnChannelOpen() + protected override void OnOpenConfirmation(uint remoteChannelNumber, uint initialWindowSize, uint maximumPacketSize) { - base.OnChannelOpen(); + base.OnOpenConfirmation(remoteChannelNumber, initialWindowSize, maximumPacketSize); this._channelOpen.Set(); } - protected override void OnChannelEof() + protected override void OnEof() { - base.OnChannelEof(); + base.OnEof(); this._channelEof.Set(); } - protected override void OnChannelClose() - { - base.OnChannelClose(); - } - protected override void OnDisposing() { diff --git a/Renci.SshClient/Renci.SshClient/Channels/ChannelForwardedTcpip.cs b/Renci.SshClient/Renci.SshClient/Channels/ChannelForwardedTcpip.cs index 460e5bd7..27d09fc4 100644 --- a/Renci.SshClient/Renci.SshClient/Channels/ChannelForwardedTcpip.cs +++ b/Renci.SshClient/Renci.SshClient/Channels/ChannelForwardedTcpip.cs @@ -89,9 +89,9 @@ namespace Renci.SshClient.Channels this.Close(); } - protected override void OnChannelData(string data) + protected override void OnData(string data) { - base.OnChannelData(data); + base.OnData(data); // Read data from the channel and send it to the port this._socket.Send(data.GetSshBytes().ToArray()); diff --git a/Renci.SshClient/Renci.SshClient/Channels/ChannelSession.cs b/Renci.SshClient/Renci.SshClient/Channels/ChannelSession.cs index fc4e54f5..8163f757 100644 --- a/Renci.SshClient/Renci.SshClient/Channels/ChannelSession.cs +++ b/Renci.SshClient/Renci.SshClient/Channels/ChannelSession.cs @@ -57,16 +57,16 @@ namespace Renci.SshClient.Channels } } - protected override void OnChannelOpen() + protected override void OnOpenConfirmation(uint remoteChannelNumber, uint initialWindowSize, uint maximumPacketSize) { - base.OnChannelOpen(); + base.OnOpenConfirmation(remoteChannelNumber, initialWindowSize, maximumPacketSize); this._channelOpenResponseWaitHandle.Set(); } - protected override void OnChannelClose() + protected override void OnClose() { - base.OnChannelClose(); + base.OnClose(); // Throw an error if exit status is not 0 if (this.ExitStatus > 0) @@ -81,9 +81,9 @@ namespace Renci.SshClient.Channels } } - protected override void OnChannelExtendedData(string data, uint dataTypeCode) + protected override void OnExtendedData(string data, uint dataTypeCode) { - base.OnChannelExtendedData(data, dataTypeCode); + base.OnExtendedData(data, dataTypeCode); if (dataTypeCode == 1) { @@ -93,7 +93,7 @@ namespace Renci.SshClient.Channels } } - protected override void OnChannelFailed(uint reasonCode, string description) + protected override void OnOpenFailure(uint reasonCode, string description, string language) { // TODO: See why occasionaly open channel will fail when try to utilze maximum number of channels @@ -108,34 +108,34 @@ namespace Renci.SshClient.Channels this._channelOpenResponseWaitHandle.Set(); } - protected override void OnChannelRequest(ChannelRequestMessage message) + protected override void OnRequest(ChannelRequestNames requestName, bool wantReply, string command, string subsystemName, uint exitStatus) { - base.OnChannelRequest(message); + base.OnRequest(requestName, wantReply, command, subsystemName, exitStatus); Message replyMessage = new ChannelFailureMessage() { - LocalChannelNumber = message.LocalChannelNumber, + LocalChannelNumber = this.LocalChannelNumber, }; - if (message.RequestName == ChannelRequestNames.ExitStatus) + if (requestName == ChannelRequestNames.ExitStatus) { - this.ExitStatus = message.ExitStatus; + this.ExitStatus = exitStatus; replyMessage = new ChannelSuccessMessage() { - LocalChannelNumber = message.LocalChannelNumber, + LocalChannelNumber = this.LocalChannelNumber, }; } - else if (message.RequestName == ChannelRequestNames.PseudoTerminal) + else if (requestName == ChannelRequestNames.PseudoTerminal) { // TODO: Check if when this request is received what to do, I suspect we receive this request when no more channel sessions are available } else { - throw new NotImplementedException(string.Format("Request name {0} is not implemented.", message.RequestName)); + throw new NotImplementedException(string.Format("Request name {0} is not implemented.", requestName)); } - if (message.WantReply) + if (wantReply) { this.SendMessage(replyMessage); } diff --git a/Renci.SshClient/Renci.SshClient/Channels/ChannelSessionExec.cs b/Renci.SshClient/Renci.SshClient/Channels/ChannelSessionExec.cs index 967b10dd..4581ec63 100644 --- a/Renci.SshClient/Renci.SshClient/Channels/ChannelSessionExec.cs +++ b/Renci.SshClient/Renci.SshClient/Channels/ChannelSessionExec.cs @@ -86,23 +86,23 @@ namespace Renci.SshClient.Channels } } - protected override void OnChannelEof() + protected override void OnEof() { - base.OnChannelEof(); + base.OnEof(); + + //this.ExecutionCompleted(); + } + + protected override void OnClose() + { + base.OnClose(); this.ExecutionCompleted(); } - protected override void OnChannelClose() + protected override void OnData(string data) { - base.OnChannelClose(); - - this.ExecutionCompleted(); - } - - protected override void OnChannelData(string data) - { - base.OnChannelData(data); + base.OnData(data); if (this._channelData != null) { @@ -118,9 +118,9 @@ namespace Renci.SshClient.Channels } } - protected override void OnChannelExtendedData(string data, uint dataTypeCode) + protected override void OnExtendedData(string data, uint dataTypeCode) { - base.OnChannelExtendedData(data, dataTypeCode); + base.OnExtendedData(data, dataTypeCode); // TODO: dataTypeCode curently ignored if (this._channelExtendedData != null) @@ -144,6 +144,7 @@ namespace Renci.SshClient.Channels this._channelExtendedData.Flush(); } + // TODO: Execute this method on different thread since it will be run on message listener this._asyncResult.IsCompleted = true; if (this._callback != null) { diff --git a/Renci.SshClient/Renci.SshClient/Channels/ChannelSessionSftp.cs b/Renci.SshClient/Renci.SshClient/Channels/ChannelSessionSftp.cs index 589d053d..9838bd04 100644 --- a/Renci.SshClient/Renci.SshClient/Channels/ChannelSessionSftp.cs +++ b/Renci.SshClient/Renci.SshClient/Channels/ChannelSessionSftp.cs @@ -205,17 +205,17 @@ namespace Renci.SshClient.Channels } - protected override void OnChannelSuccess() + protected override void OnSuccess() { - base.OnChannelSuccess(); + base.OnSuccess(); this._channelRequestSuccessWaitHandle.Set(); } - protected override void OnChannelData(string data) + protected override void OnData(string data) { - base.OnChannelData(data); + base.OnData(data); if (this._packetData == null) { diff --git a/Renci.SshClient/Renci.SshClient/ForwardedPortRemote.cs b/Renci.SshClient/Renci.SshClient/ForwardedPortRemote.cs index ddd7e41a..ca94f6a2 100644 --- a/Renci.SshClient/Renci.SshClient/ForwardedPortRemote.cs +++ b/Renci.SshClient/Renci.SshClient/ForwardedPortRemote.cs @@ -22,7 +22,7 @@ namespace Renci.SshClient this.Session.RequestSuccess += Session_RequestSuccess; this.Session.RequestFailure += Session_RequestFailure; - this.Session.ChannelOpening += Session_ChannelOpening; + this.Session.ChannelOpen += Session_ChannelOpening; // Send global request to start direct tcpip this.Session.SendMessage(new GlobalRequestMessage @@ -38,7 +38,7 @@ namespace Renci.SshClient if (!this._requestStatus) { // If request failed dont handle channel opening for this request - this.Session.ChannelOpening -= Session_ChannelOpening; + this.Session.ChannelOpen -= Session_ChannelOpening; } } @@ -57,10 +57,10 @@ namespace Renci.SshClient this.Session.RequestSuccess -= Session_RequestSuccess; this.Session.RequestFailure -= Session_RequestFailure; - this.Session.ChannelOpening -= Session_ChannelOpening; + this.Session.ChannelOpen -= Session_ChannelOpening; } - private void Session_ChannelOpening(object sender, ChannelOpeningEventArgs e) + private void Session_ChannelOpening(object sender, MessageEventArgs e) { // Ensure that this is corresponding request if (e.Message.ConnectedAddress == this.ConnectedHost && e.Message.ConnectedPort == this.BoundPort) @@ -86,12 +86,12 @@ namespace Renci.SshClient this._globalRequestResponse.Set(); } - private void Session_RequestSuccess(object sender, RequestSuccessEventArgs e) + private void Session_RequestSuccess(object sender, MessageEventArgs e) { this._requestStatus = true; if (this.BoundPort == 0) { - this.BoundPort = e.BoundPort; + this.BoundPort = (e.Message.BoundPort == null) ? 0 : e.Message.BoundPort.Value; } this._globalRequestResponse.Set(); diff --git a/Renci.SshClient/Renci.SshClient/MessageEventArgs.cs b/Renci.SshClient/Renci.SshClient/MessageEventArgs.cs new file mode 100644 index 00000000..0c0304b3 --- /dev/null +++ b/Renci.SshClient/Renci.SshClient/MessageEventArgs.cs @@ -0,0 +1,14 @@ +using System; + +namespace Renci.SshClient +{ + internal class MessageEventArgs : EventArgs + { + public T Message { get; private set; } + + public MessageEventArgs(T message) + { + this.Message = message; + } + } +} diff --git a/Renci.SshClient/Renci.SshClient/Renci.SshClient.csproj b/Renci.SshClient/Renci.SshClient/Renci.SshClient.csproj index e1785a65..8a029d56 100644 --- a/Renci.SshClient/Renci.SshClient/Renci.SshClient.csproj +++ b/Renci.SshClient/Renci.SshClient/Renci.SshClient.csproj @@ -60,7 +60,7 @@ - + @@ -73,7 +73,6 @@ - diff --git a/Renci.SshClient/Renci.SshClient/RequestSuccessEventArgs.cs b/Renci.SshClient/Renci.SshClient/RequestSuccessEventArgs.cs deleted file mode 100644 index 78e17fea..00000000 --- a/Renci.SshClient/Renci.SshClient/RequestSuccessEventArgs.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace Renci.SshClient -{ - internal class RequestSuccessEventArgs : EventArgs - { - public uint BoundPort { get; set; } - } -} diff --git a/Renci.SshClient/Renci.SshClient/Session.cs b/Renci.SshClient/Renci.SshClient/Session.cs index ecaf295a..535798c2 100644 --- a/Renci.SshClient/Renci.SshClient/Session.cs +++ b/Renci.SshClient/Renci.SshClient/Session.cs @@ -198,11 +198,79 @@ namespace Renci.SshClient /// The connection info. public ConnectionInfo ConnectionInfo { get; private set; } - public event EventHandler ChannelOpening; + #region Message events - public event EventHandler RequestSuccess; + /// + /// Occurs when message received + /// + public event EventHandler> GlobalRequest; - public event EventHandler RequestFailure; + /// + /// Occurs when message received + /// + public event EventHandler> RequestSuccess; + + /// + /// Occurs when message received + /// + public event EventHandler> RequestFailure; + + /// + /// Occurs when message received + /// + public event EventHandler> ChannelOpen; + + /// + /// Occurs when message received + /// + public event EventHandler> ChannelOpenConfirmation; + + /// + /// Occurs when message received + /// + public event EventHandler> ChannelOpenFailure; + + /// + /// Occurs when message received + /// + public event EventHandler> ChannelWindowAdjust; + + /// + /// Occurs when message received + /// + public event EventHandler> ChannelData; + + /// + /// Occurs when message received + /// + public event EventHandler> ChannelExtendedData; + + /// + /// Occurs when message received + /// + public event EventHandler> ChannelEof; + + /// + /// Occurs when message received + /// + public event EventHandler> ChannelClose; + + /// + /// Occurs when message received + /// + public event EventHandler> ChannelRequest; + + /// + /// Occurs when message received + /// + public event EventHandler> ChannelSuccess; + + /// + /// Occurs when message received + /// + public event EventHandler> ChannelFailure; + + #endregion /// /// Initializes a new instance of the class. @@ -401,16 +469,6 @@ namespace Renci.SshClient lock (this) { channel.Initialize(this, serverChannelNumber, windowSize, packetSize); - try - { - - this._sessionChannels.Add(channel.LocalChannelNumber, channel); - } - catch (Exception exp) - { - - throw; - } } return channel; } @@ -623,10 +681,10 @@ namespace Renci.SshClient protected void HandleMessage(T message) where T : Message { // Do nothing as message could be proccessed by other module - if (message is ChannelMessage) - { - this.HandleMessage(message as ChannelMessage); - } + //if (message is ChannelMessage) + //{ + // this.HandleMessage(message as ChannelMessage); + //} } #region Handle transport messages @@ -675,18 +733,17 @@ namespace Renci.SshClient protected virtual void HandleMessage(GlobalRequestMessage message) { - // TODO: Add implemention for this message + if (this.GlobalRequest != null) + { + this.GlobalRequest(this, new MessageEventArgs(message)); + } } protected virtual void HandleMessage(RequestSuccessMessage message) { - // TODO: Add implemention for this message if (this.RequestSuccess != null) { - this.RequestSuccess(this, new RequestSuccessEventArgs - { - BoundPort = (message.BoundPort == null) ? 0 : message.BoundPort.Value, - }); + this.RequestSuccess(this, new MessageEventArgs(message)); } } @@ -694,54 +751,99 @@ namespace Renci.SshClient { if (this.RequestFailure != null) { - this.RequestFailure(this, new EventArgs()); + this.RequestFailure(this, new MessageEventArgs(message)); } } #endregion - #region Handle channel messages + #region Handle channel messages and raise channel events protected void HandleMessage(ChannelOpenMessage message) { - - if (this.ChannelOpening != null) + if (this.ChannelOpen != null) { - this.ChannelOpening(this, new ChannelOpeningEventArgs - { - Message = message, - }); + this.ChannelOpen(this, new MessageEventArgs(message)); } } - protected void HandleMessage(ChannelMessage message) - { - // TODO: Improve session channel managment, sometimes it sends a message that is not in sessionChannels collection - this._sessionChannels[message.LocalChannelNumber].HandleChannelMessage(message); - } - protected void HandleMessage(ChannelOpenConfirmationMessage message) { - this.HandleMessage((ChannelMessage)message); + if (this.ChannelOpenConfirmation != null) + { + this.ChannelOpenConfirmation(this, new MessageEventArgs(message)); + } + } + + protected void HandleMessage(ChannelOpenFailureMessage message) + { + if (this.ChannelOpenFailure != null) + { + this.ChannelOpenFailure(this, new MessageEventArgs(message)); + } + } + + protected void HandleMessage(ChannelWindowAdjustMessage message) + { + if (this.ChannelWindowAdjust != null) + { + this.ChannelWindowAdjust(this, new MessageEventArgs(message)); + } + } + + protected void HandleMessage(ChannelDataMessage message) + { + if (this.ChannelData != null) + { + this.ChannelData(this, new MessageEventArgs(message)); + } + } + + protected void HandleMessage(ChannelExtendedDataMessage message) + { + if (this.ChannelExtendedData != null) + { + this.ChannelExtendedData(this, new MessageEventArgs(message)); + } + } + + protected void HandleMessage(ChannelEofMessage message) + { + if (this.ChannelEof != null) + { + this.ChannelEof(this, new MessageEventArgs(message)); + } } protected void HandleMessage(ChannelCloseMessage message) { - this.HandleMessage((ChannelMessage)message); - - lock (this._sessionChannels) + if (this.ChannelClose != null) { - this._sessionChannels.Remove(message.LocalChannelNumber); + this.ChannelClose(this, new MessageEventArgs(message)); + } + } + + protected void HandleMessage(ChannelRequestMessage message) + { + if (this.ChannelRequest != null) + { + this.ChannelRequest(this, new MessageEventArgs(message)); + } + } + + protected void HandleMessage(ChannelSuccessMessage message) + { + if (this.ChannelSuccess != null) + { + this.ChannelSuccess(this, new MessageEventArgs(message)); } } protected void HandleMessage(ChannelFailureMessage message) { - this.HandleMessage((ChannelMessage)message); - - lock (this._sessionChannels) + if (this.ChannelFailure != null) { - this._sessionChannels.Remove(message.LocalChannelNumber); + this.ChannelFailure(this, new MessageEventArgs(message)); } } @@ -974,11 +1076,15 @@ namespace Renci.SshClient } else { + // TODO: Handle each message on induvidual thread + //Task.Factory.StartNew(() => + //{ // Handle message this.HandleMessage((dynamic)message); // Raise an event that message received this.RaiseMessageReceived(this, new MessageReceivedEventArgs(message)); + //}); } } catch (SshException exp)