diff --git a/Renci.SshClient/Renci.SshClient/Channels/Channel.cs b/Renci.SshClient/Renci.SshClient/Channels/Channel.cs index 89580aa2..c900b647 100644 --- a/Renci.SshClient/Renci.SshClient/Channels/Channel.cs +++ b/Renci.SshClient/Renci.SshClient/Channels/Channel.cs @@ -18,8 +18,7 @@ namespace Renci.SshClient.Channels private uint _initialWindowSize = 0x100000; - //private uint _maximumPacketSize = 0x4000; - private uint _maximumPacketSize = 1024; + private uint _maximumPacketSize = 0x4000; public abstract ChannelTypes ChannelType { get; } diff --git a/Renci.SshClient/Renci.SshClient/ConnectionInfo.cs b/Renci.SshClient/Renci.SshClient/ConnectionInfo.cs index 0006a3d7..a27f31fa 100644 --- a/Renci.SshClient/Renci.SshClient/ConnectionInfo.cs +++ b/Renci.SshClient/Renci.SshClient/ConnectionInfo.cs @@ -12,10 +12,13 @@ public PrivateKeyFile KeyFile { get; set; } + public int Timeout { get; set; } + public ConnectionInfo() { // Set default connection values this.Port = 22; + this.Timeout = 1000 * 10; // Set default timeout to 10 sec } } } diff --git a/Renci.SshClient/Renci.SshClient/Session.cs b/Renci.SshClient/Renci.SshClient/Session.cs index a8941057..c2cdaa66 100644 --- a/Renci.SshClient/Renci.SshClient/Session.cs +++ b/Renci.SshClient/Renci.SshClient/Session.cs @@ -22,6 +22,11 @@ namespace Renci.SshClient { protected const int MAXIMUM_PACKET_SIZE = 35000; + /// + /// Creates new session using connection informaiton. + /// + /// The connection info. + /// New version specific session. public static Session CreateSession(ConnectionInfo connectionInfo) { var ep = new IPEndPoint(Dns.GetHostAddresses(connectionInfo.Host)[0], connectionInfo.Port); @@ -32,7 +37,7 @@ namespace Renci.SshClient // Connect socket with 5 seconds timeout var connectResult = socket.BeginConnect(ep, null, null); - connectResult.AsyncWaitHandle.WaitOne(1000 * 5); + connectResult.AsyncWaitHandle.WaitOne(connectionInfo.Timeout); socket.EndConnect(connectResult); @@ -62,26 +67,46 @@ namespace Renci.SshClient return session; } + /// + /// Holds connection socket. + /// private Socket _socket; + /// + /// Holds connection socket stream to communicate with the server + /// private NetworkStream _socketStream; - private int _waitTimeout = 1000 * 10; // Default 10 sec wait timeout - + /// + /// Holds reference to key exchange algorithm being used by this connection + /// private KeyExchange _keyExhcange; + /// + /// Holds reference to task that listnes for incoming messages + /// private Task _messageListener; + /// + /// WaitHandle to signal that key exchange was finished, weither it was succesfull or not. + /// private EventWaitHandle _keyExhangedFinishedWaitHandle = new AutoResetEvent(false); + /// + /// WaitHandle to signale that last service request was accepted + /// private EventWaitHandle _serviceAccepted = new AutoResetEvent(false); + /// + /// WaitHandle to signal that exception was thrown by another thread. + /// private EventWaitHandle _exceptionWaitHandle = new AutoResetEvent(false); + /// + /// Keeps track of all open channels + /// private IDictionary _openChannels = new Dictionary(); - private IDictionary _executedAuthenticationMethods = new Dictionary(); - /// /// Exception that need to be thrown by waiting thread /// @@ -92,10 +117,21 @@ namespace Renci.SshClient /// private bool _isAuthenticated; + /// + /// Occurs when new message received. + /// public event EventHandler MessageReceived; + /// + /// Gets or sets the HMAC algorithm to use when receiving message from the server. + /// + /// The server mac. protected HMAC ServerMac { get; private set; } + /// + /// Gets or sets the HMAC algorithm to use when sending message to the server. + /// + /// The client mac. protected HMAC ClientMac { get; private set; } /// @@ -110,8 +146,16 @@ namespace Renci.SshClient /// The server cipher. protected Cipher ServerCipher { get; private set; } + /// + /// Gets or sets the compression algorithm to use when receiving message from the server. + /// + /// The server decompression. protected Compression ServerDecompression { get; private set; } + /// + /// Gets or sets the compression algorithm to use when sending message to the server. + /// + /// The client compression. protected Compression ClientCompression { get; private set; } /// @@ -125,12 +169,30 @@ namespace Renci.SshClient // TODO: Consider refactor to make setter private public IEnumerable SessionId { get; set; } + /// + /// Gets or sets the server version string. + /// + /// The server version. public string ServerVersion { get; private set; } + /// + /// Gets or sets the client version string. + /// + /// The client version. public string ClientVersion { get; private set; } + /// + /// Gets or sets the connection info. + /// + /// The connection info. public ConnectionInfo ConnectionInfo { get; private set; } + /// + /// Initializes a new instance of the class. + /// + /// The connection info. + /// The socket. + /// The server version. protected Session(ConnectionInfo connectionInfo, Socket socket, string serverVersion) { this.ConnectionInfo = connectionInfo; @@ -150,6 +212,11 @@ namespace Renci.SshClient {typeof(ChannelSftp), (session) => { return new ChannelSftp(session);}} }; + /// + /// Creates the new channel. + /// + /// Type of channel to create. + /// New channel of specified type public T CreateChannel() where T : Channel { if (!this.IsConnected) @@ -159,6 +226,9 @@ namespace Renci.SshClient return _channels[typeof(T)](this) as T; } + /// + /// Connects to the server. + /// public void Connect() { lock (this._socket) @@ -229,6 +299,9 @@ namespace Renci.SshClient } } + /// + /// Disconnects from the server + /// public void Disconnect() { // TODO: Change message to something more appropriate @@ -237,8 +310,16 @@ namespace Renci.SshClient this.DisconnectCleanup(); } + /// + /// Sends packet message to the server. + /// + /// The message. internal abstract void SendMessage(Message message); + /// + /// Waits for handle to signal while checking other handles as well including timeout check to prevent waiting for ever + /// + /// The wait handle. internal void WaitHandle(WaitHandle waitHandle) { var waitHandles = new WaitHandle[] @@ -254,7 +335,7 @@ namespace Renci.SshClient #if NOTIMEOUT index = EventWaitHandle.WaitAny(waitHandles); #else - index = EventWaitHandle.WaitAny(waitHandles, this._waitTimeout); + index = EventWaitHandle.WaitAny(waitHandles, this.ConnectionInfo.Timeout); #endif if (this._exceptionToThrow != null) { @@ -269,8 +350,17 @@ namespace Renci.SshClient } } + /// + /// Receives the message from the server. + /// + /// protected abstract Message ReceiveMessage(); + /// + /// Handles the message. + /// + /// + /// The message. protected virtual void HandleMessage(T message) where T : Message { // Do nothing as message could be proccessed by other module @@ -368,6 +458,11 @@ namespace Renci.SshClient #endregion + /// + /// Disconnects client from the server with specified reason code. + /// + /// The reason code. + /// The message. protected void Disconnect(DisconnectReasonCodes reasonCode, string message) { if (this.IsConnected) @@ -382,6 +477,11 @@ namespace Renci.SshClient } } + /// + /// Reads the specified length of bytes from the server + /// + /// The length. + /// protected byte[] Read(int length) { var buffer = new byte[length]; @@ -429,6 +529,10 @@ namespace Renci.SshClient } + /// + /// Writes the specified data to the server. + /// + /// The data. protected void Write(byte[] data) { try @@ -443,6 +547,9 @@ namespace Renci.SshClient } } + /// + /// Initiates new key request by the client + /// protected void RequestNewKeys() { // TODO: Create method to issue new keys when required @@ -498,6 +605,9 @@ namespace Renci.SshClient #endregion + /// + /// Perfom neccesary cleanup when client disconects from the server + /// private void DisconnectCleanup() { // Stop running listener thread @@ -519,6 +629,9 @@ namespace Renci.SshClient } } + /// + /// Listnets for incoming message from the server and handles them. This method run as a task on seperate thread. + /// private void MessageListener() { try @@ -552,6 +665,11 @@ namespace Renci.SshClient } } + /// + /// Raises the MessageReceived event. + /// + /// The sender. + /// The instance containing the event data. private void RaiseMessageReceived(object sender, MessageReceivedEventArgs args) { if (this.MessageReceived != null) @@ -560,12 +678,20 @@ namespace Renci.SshClient } } + /// + /// Handles message. + /// + /// The message. private void HandleMessage(ChannelOpenConfirmationMessage message) { // Keep track of open channels this._openChannels.Add(message.ChannelNumber, message.ServerChannelNumber); } + /// + /// Handles message. + /// + /// The message. private void HandleMessage(ChannelCloseMessage message) { // Keep track of open channels