mirror of
https://github.com/sshnet/SSH.NET.git
synced 2026-09-10 09:15:47 +00:00
Refactor channel message handling by converting into events
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
using System;
|
||||
using Renci.SshClient.Messages.Connection;
|
||||
|
||||
namespace Renci.SshClient
|
||||
{
|
||||
internal class ChannelOpeningEventArgs : EventArgs
|
||||
{
|
||||
public ChannelOpenMessage Message { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,18 @@ namespace Renci.SshClient.Channels
|
||||
this.Session.RegisterMessageType<ChannelEofMessage>(MessageTypes.ChannelEof);
|
||||
this.Session.RegisterMessageType<ChannelCloseMessage>(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>(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<ChannelOpenMessage> 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<ChannelOpenConfirmationMessage> 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<ChannelOpenFailureMessage> 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<ChannelWindowAdjustMessage> 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<ChannelDataMessage> 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<ChannelExtendedDataMessage> 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<ChannelEofMessage> e)
|
||||
{
|
||||
this.OnChannelSuccess();
|
||||
if (e.Message.LocalChannelNumber == this.LocalChannelNumber)
|
||||
{
|
||||
this.OnEof();
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleMessage(ChannelEofMessage message)
|
||||
private void OnChannelClose(object sender, MessageEventArgs<ChannelCloseMessage> 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<ChannelRequestMessage> 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<ChannelSuccessMessage> e)
|
||||
{
|
||||
if (e.Message.LocalChannelNumber == this.LocalChannelNumber)
|
||||
{
|
||||
this.OnSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
this._channelClosedWaitHandle.Set();
|
||||
private void OnChannelFailure(object sender, MessageEventArgs<ChannelFailureMessage> 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();
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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<ChannelOpenMessage> 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<RequestSuccessMessage> 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();
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
|
||||
namespace Renci.SshClient
|
||||
{
|
||||
internal class MessageEventArgs<T> : EventArgs
|
||||
{
|
||||
public T Message { get; private set; }
|
||||
|
||||
public MessageEventArgs(T message)
|
||||
{
|
||||
this.Message = message;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,7 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ChannelOpeningEventArgs.cs" />
|
||||
<Compile Include="MessageEventArgs.cs" />
|
||||
<Compile Include="Channels\ChannelAsyncResult.cs" />
|
||||
<Compile Include="Channels\ChannelEventArgs.cs" />
|
||||
<Compile Include="Channels\ChannelDirectTcpip.cs" />
|
||||
@@ -73,7 +73,6 @@
|
||||
<Compile Include="ForwardedPortRemote.cs" />
|
||||
<Compile Include="Messages\Connection\ChannelOpenDirectTcpIPMessage.cs" />
|
||||
<Compile Include="Messages\Connection\GlobalRequestNames.cs" />
|
||||
<Compile Include="RequestSuccessEventArgs.cs" />
|
||||
<Compile Include="Security\Algorithm.cs" />
|
||||
<Compile Include="Security\Cipher.cs" />
|
||||
<Compile Include="Security\CipherAES.cs" />
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Renci.SshClient
|
||||
{
|
||||
internal class RequestSuccessEventArgs : EventArgs
|
||||
{
|
||||
public uint BoundPort { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -198,11 +198,79 @@ namespace Renci.SshClient
|
||||
/// <value>The connection info.</value>
|
||||
public ConnectionInfo ConnectionInfo { get; private set; }
|
||||
|
||||
public event EventHandler<ChannelOpeningEventArgs> ChannelOpening;
|
||||
#region Message events
|
||||
|
||||
public event EventHandler<RequestSuccessEventArgs> RequestSuccess;
|
||||
/// <summary>
|
||||
/// Occurs when <see cref="GlobalRequestMessage"/> message received
|
||||
/// </summary>
|
||||
public event EventHandler<MessageEventArgs<GlobalRequestMessage>> GlobalRequest;
|
||||
|
||||
public event EventHandler RequestFailure;
|
||||
/// <summary>
|
||||
/// Occurs when <see cref="RequestSuccessMessage"/> message received
|
||||
/// </summary>
|
||||
public event EventHandler<MessageEventArgs<RequestSuccessMessage>> RequestSuccess;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when <see cref="RequestFailureMessage"/> message received
|
||||
/// </summary>
|
||||
public event EventHandler<MessageEventArgs<RequestFailureMessage>> RequestFailure;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when <see cref="ChannelOpenMessage"/> message received
|
||||
/// </summary>
|
||||
public event EventHandler<MessageEventArgs<ChannelOpenMessage>> ChannelOpen;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when <see cref="ChannelOpenConfirmationMessage"/> message received
|
||||
/// </summary>
|
||||
public event EventHandler<MessageEventArgs<ChannelOpenConfirmationMessage>> ChannelOpenConfirmation;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when <see cref="ChannelOpenFailureMessage"/> message received
|
||||
/// </summary>
|
||||
public event EventHandler<MessageEventArgs<ChannelOpenFailureMessage>> ChannelOpenFailure;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when <see cref="ChannelWindowAdjustMessage"/> message received
|
||||
/// </summary>
|
||||
public event EventHandler<MessageEventArgs<ChannelWindowAdjustMessage>> ChannelWindowAdjust;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when <see cref="ChannelDataMessage"/> message received
|
||||
/// </summary>
|
||||
public event EventHandler<MessageEventArgs<ChannelDataMessage>> ChannelData;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when <see cref="ChannelExtendedDataMessage"/> message received
|
||||
/// </summary>
|
||||
public event EventHandler<MessageEventArgs<ChannelExtendedDataMessage>> ChannelExtendedData;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when <see cref="ChannelEofMessage"/> message received
|
||||
/// </summary>
|
||||
public event EventHandler<MessageEventArgs<ChannelEofMessage>> ChannelEof;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when <see cref="ChannelCloseMessage"/> message received
|
||||
/// </summary>
|
||||
public event EventHandler<MessageEventArgs<ChannelCloseMessage>> ChannelClose;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when <see cref="ChannelRequestMessage"/> message received
|
||||
/// </summary>
|
||||
public event EventHandler<MessageEventArgs<ChannelRequestMessage>> ChannelRequest;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when <see cref="ChannelSuccessMessage"/> message received
|
||||
/// </summary>
|
||||
public event EventHandler<MessageEventArgs<ChannelSuccessMessage>> ChannelSuccess;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when <see cref="ChannelFailureMessage"/> message received
|
||||
/// </summary>
|
||||
public event EventHandler<MessageEventArgs<ChannelFailureMessage>> ChannelFailure;
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Session"/> 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>(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<GlobalRequestMessage>(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<RequestSuccessMessage>(message));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -694,54 +751,99 @@ namespace Renci.SshClient
|
||||
{
|
||||
if (this.RequestFailure != null)
|
||||
{
|
||||
this.RequestFailure(this, new EventArgs());
|
||||
this.RequestFailure(this, new MessageEventArgs<RequestFailureMessage>(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<ChannelOpenMessage>(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<ChannelOpenConfirmationMessage>(message));
|
||||
}
|
||||
}
|
||||
|
||||
protected void HandleMessage(ChannelOpenFailureMessage message)
|
||||
{
|
||||
if (this.ChannelOpenFailure != null)
|
||||
{
|
||||
this.ChannelOpenFailure(this, new MessageEventArgs<ChannelOpenFailureMessage>(message));
|
||||
}
|
||||
}
|
||||
|
||||
protected void HandleMessage(ChannelWindowAdjustMessage message)
|
||||
{
|
||||
if (this.ChannelWindowAdjust != null)
|
||||
{
|
||||
this.ChannelWindowAdjust(this, new MessageEventArgs<ChannelWindowAdjustMessage>(message));
|
||||
}
|
||||
}
|
||||
|
||||
protected void HandleMessage(ChannelDataMessage message)
|
||||
{
|
||||
if (this.ChannelData != null)
|
||||
{
|
||||
this.ChannelData(this, new MessageEventArgs<ChannelDataMessage>(message));
|
||||
}
|
||||
}
|
||||
|
||||
protected void HandleMessage(ChannelExtendedDataMessage message)
|
||||
{
|
||||
if (this.ChannelExtendedData != null)
|
||||
{
|
||||
this.ChannelExtendedData(this, new MessageEventArgs<ChannelExtendedDataMessage>(message));
|
||||
}
|
||||
}
|
||||
|
||||
protected void HandleMessage(ChannelEofMessage message)
|
||||
{
|
||||
if (this.ChannelEof != null)
|
||||
{
|
||||
this.ChannelEof(this, new MessageEventArgs<ChannelEofMessage>(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<ChannelCloseMessage>(message));
|
||||
}
|
||||
}
|
||||
|
||||
protected void HandleMessage(ChannelRequestMessage message)
|
||||
{
|
||||
if (this.ChannelRequest != null)
|
||||
{
|
||||
this.ChannelRequest(this, new MessageEventArgs<ChannelRequestMessage>(message));
|
||||
}
|
||||
}
|
||||
|
||||
protected void HandleMessage(ChannelSuccessMessage message)
|
||||
{
|
||||
if (this.ChannelSuccess != null)
|
||||
{
|
||||
this.ChannelSuccess(this, new MessageEventArgs<ChannelSuccessMessage>(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<ChannelFailureMessage>(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)
|
||||
|
||||
Reference in New Issue
Block a user