mirror of
https://github.com/sshnet/SSH.NET.git
synced 2026-09-10 09:15:47 +00:00
Minor channel communication improvemtns, disconecting and error handeling improved
This commit is contained in:
@@ -13,7 +13,7 @@ namespace Renci.SshClient.Channels
|
||||
|
||||
private uint _initialWindowSize = 0x100000;
|
||||
|
||||
private uint _maximumPacketSize = 0x4000;
|
||||
private uint _maximumPacketSize = 0x8000;
|
||||
|
||||
/// <summary>
|
||||
/// Counts faile channel open attempts
|
||||
@@ -196,10 +196,19 @@ namespace Renci.SshClient.Channels
|
||||
if (message.RequestName == RequestNames.ExitStatus)
|
||||
{
|
||||
var exitStatus = message.ExitStatus;
|
||||
|
||||
replyMessage = new ChannelSuccessMessage()
|
||||
{
|
||||
ChannelNumber = message.ChannelNumber,
|
||||
};
|
||||
|
||||
this.SendChannelCloseMessage();
|
||||
|
||||
// TODO: if exitStatus is not 0 then throw an exception or notify user that command failed to execute correctly
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException(string.Format("Request name {0} is not implemented.", message.RequestName));
|
||||
}
|
||||
|
||||
if (message.WantReply)
|
||||
@@ -229,6 +238,8 @@ namespace Renci.SshClient.Channels
|
||||
this._channelClosedWaitHandle.Set();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void AdjustDataWindow(string messageData)
|
||||
{
|
||||
this.WindowSize -= (uint)messageData.Length;
|
||||
@@ -245,8 +256,6 @@ namespace Renci.SshClient.Channels
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void RaiseOpened()
|
||||
{
|
||||
if (this.Opened != null)
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Renci.SshClient.Channels
|
||||
}
|
||||
|
||||
public ChannelExec(Session session, uint channelId)
|
||||
: base(session, channelId, 0x100000, 0x1000)
|
||||
: base(session, channelId, 0x100000, 0x8000)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -47,7 +47,6 @@ namespace Renci.SshClient.Channels
|
||||
};
|
||||
|
||||
this._callback = callback;
|
||||
|
||||
this._channelData = output;
|
||||
this._channelExtendedData = extendedOutput;
|
||||
|
||||
@@ -67,26 +66,34 @@ namespace Renci.SshClient.Channels
|
||||
|
||||
internal void EndExecute(IAsyncResult result)
|
||||
{
|
||||
ChannelAsyncResult channelAsyncResult = result as ChannelAsyncResult;
|
||||
|
||||
if (channelAsyncResult.Channel != this)
|
||||
try
|
||||
{
|
||||
throw new InvalidOperationException("Invalid IAsyncResult parameter");
|
||||
ChannelAsyncResult channelAsyncResult = result as ChannelAsyncResult;
|
||||
|
||||
if (channelAsyncResult.Channel != this)
|
||||
{
|
||||
throw new InvalidOperationException("Invalid IAsyncResult parameter");
|
||||
}
|
||||
|
||||
//Make sure that operation completed if not wait for it to finish
|
||||
this.Session.WaitHandle(this._asyncResult.AsyncWaitHandle);
|
||||
|
||||
this.Close();
|
||||
|
||||
this._asyncResult = null;
|
||||
|
||||
if (this._exception != null)
|
||||
{
|
||||
var exception = this._exception;
|
||||
this._exception = null; // Clean exception
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
//Make sure that operation completed if not wait for it to finish
|
||||
this.Session.WaitHandle(this._asyncResult.AsyncWaitHandle);
|
||||
|
||||
this.Close();
|
||||
|
||||
this._asyncResult = null;
|
||||
|
||||
if (this._exception != null)
|
||||
{
|
||||
var exception = this._exception;
|
||||
this._exception = null; // Clean exception
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnChannelEof()
|
||||
@@ -96,6 +103,13 @@ namespace Renci.SshClient.Channels
|
||||
this.ExecutionCompleted();
|
||||
}
|
||||
|
||||
protected override void OnChannelClose()
|
||||
{
|
||||
base.OnChannelClose();
|
||||
|
||||
this.ExecutionCompleted();
|
||||
}
|
||||
|
||||
protected override void OnChannelFailed(uint reasonCode, string description)
|
||||
{
|
||||
base.OnChannelFailed(reasonCode, description);
|
||||
|
||||
@@ -126,12 +126,12 @@ namespace Renci.SshClient.Common
|
||||
|
||||
public bool IsSynchronized
|
||||
{
|
||||
get { throw new System.NotImplementedException(); }
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public object SyncRoot
|
||||
{
|
||||
get { throw new System.NotImplementedException(); }
|
||||
get { return this; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -72,6 +72,11 @@ namespace Renci.SshClient
|
||||
/// </summary>
|
||||
private EventWaitHandle _exceptionWaitHandle = new AutoResetEvent(false);
|
||||
|
||||
/// <summary>
|
||||
/// WaitHandle to signal that listner ended
|
||||
/// </summary>
|
||||
private EventWaitHandle _listenerWaitHandle = new AutoResetEvent(false);
|
||||
|
||||
/// <summary>
|
||||
/// Keeps track of all open channels
|
||||
/// </summary>
|
||||
@@ -87,6 +92,11 @@ namespace Renci.SshClient
|
||||
/// </summary>
|
||||
private bool _isAuthenticated;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies weither Disconnect method was called
|
||||
/// </summary>
|
||||
private bool _isDisconnecting;
|
||||
|
||||
/// <summary>
|
||||
/// holds number to be used for session channels
|
||||
/// </summary>
|
||||
@@ -233,15 +243,18 @@ namespace Renci.SshClient
|
||||
if (this.IsConnected)
|
||||
return;
|
||||
|
||||
lock (this)
|
||||
try
|
||||
{
|
||||
// If connected dont connect again
|
||||
_authenticationConnection.Wait();
|
||||
|
||||
if (this.IsConnected)
|
||||
return;
|
||||
|
||||
try
|
||||
lock (this)
|
||||
{
|
||||
_authenticationConnection.Wait();
|
||||
// If connected dont connect again
|
||||
if (this.IsConnected)
|
||||
return;
|
||||
|
||||
var ep = new IPEndPoint(Dns.GetHostAddresses(connectionInfo.Host)[0], connectionInfo.Port);
|
||||
this._socket = new Socket(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
||||
@@ -331,11 +344,13 @@ namespace Renci.SshClient
|
||||
{
|
||||
throw new AuthenticationException(errorMessage ?? "User cannot be authenticated.");
|
||||
}
|
||||
|
||||
Monitor.Pulse(this);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_authenticationConnection.Release();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_authenticationConnection.Release();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,7 +359,8 @@ namespace Renci.SshClient
|
||||
/// </summary>
|
||||
public void Disconnect()
|
||||
{
|
||||
// TODO: Change message to something more appropriate
|
||||
this._isDisconnecting = true;
|
||||
|
||||
this.Disconnect(DisconnectReasonCodes.ByApplication, "Connection terminated by the client.");
|
||||
|
||||
this.DisconnectCleanup();
|
||||
@@ -359,6 +375,7 @@ namespace Renci.SshClient
|
||||
var waitHandles = new WaitHandle[]
|
||||
{
|
||||
this._exceptionWaitHandle,
|
||||
this._listenerWaitHandle, // When listener exits
|
||||
waitHandle,
|
||||
};
|
||||
|
||||
@@ -491,7 +508,7 @@ namespace Renci.SshClient
|
||||
|
||||
// Test packet minimum and maximum boundaries
|
||||
if (packetLength < Math.Max((byte)16, blockSize) - 4 || packetLength > Session.MAXIMUM_PACKET_SIZE - 4)
|
||||
throw new InvalidOperationException(string.Format("Bad packet length {0}", packetLength));
|
||||
throw new IOException(string.Format("Bad packet length {0}", packetLength));
|
||||
|
||||
// Read rest of the packet data
|
||||
int bytesToRead = (int)(packetLength - (blockSize - 4));
|
||||
@@ -525,7 +542,7 @@ namespace Renci.SshClient
|
||||
|
||||
if (!serverHash.IsEqualTo(clientHash))
|
||||
{
|
||||
throw new InvalidOperationException("MAC error");
|
||||
throw new IOException("MAC error");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -839,9 +856,19 @@ namespace Renci.SshClient
|
||||
this.RaiseMessageReceived(this, new MessageReceivedEventArgs(message));
|
||||
}
|
||||
}
|
||||
catch (IOException)
|
||||
catch (IOException exp)
|
||||
{
|
||||
// Ignore this error since socket was disconected
|
||||
|
||||
// Ensure socket is disconnected
|
||||
this._socket.Close();
|
||||
|
||||
if (!this._isDisconnecting)
|
||||
{
|
||||
this._exceptionToThrow = exp;
|
||||
|
||||
this._exceptionWaitHandle.Set();
|
||||
}
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
@@ -854,6 +881,8 @@ namespace Renci.SshClient
|
||||
|
||||
this._exceptionWaitHandle.Set();
|
||||
}
|
||||
|
||||
this._listenerWaitHandle.Set();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -910,6 +939,11 @@ namespace Renci.SshClient
|
||||
{
|
||||
this._exceptionWaitHandle.Dispose();
|
||||
}
|
||||
|
||||
if (this._listenerWaitHandle != null)
|
||||
{
|
||||
this._listenerWaitHandle.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
// Note disposing has been done.
|
||||
|
||||
Reference in New Issue
Block a user