ClientChannel.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. using System;
  2. using Renci.SshNet.Common;
  3. using Renci.SshNet.Messages.Connection;
  4. namespace Renci.SshNet.Channels
  5. {
  6. internal abstract class ClientChannel : Channel
  7. {
  8. /// <summary>
  9. /// Initializes a new <see cref="ClientChannel"/> instance.
  10. /// </summary>
  11. /// <param name="session">The session.</param>
  12. /// <param name="localChannelNumber">The local channel number.</param>
  13. /// <param name="localWindowSize">Size of the window.</param>
  14. /// <param name="localPacketSize">Size of the packet.</param>
  15. protected ClientChannel(ISession session, uint localChannelNumber, uint localWindowSize, uint localPacketSize)
  16. : base(session, localChannelNumber, localWindowSize, localPacketSize)
  17. {
  18. session.ChannelOpenConfirmationReceived += OnChannelOpenConfirmation;
  19. session.ChannelOpenFailureReceived += OnChannelOpenFailure;
  20. }
  21. /// <summary>
  22. /// Occurs when <see cref="ChannelOpenConfirmationMessage"/> is received.
  23. /// </summary>
  24. public event EventHandler<ChannelOpenConfirmedEventArgs> OpenConfirmed;
  25. /// <summary>
  26. /// Occurs when <see cref="ChannelOpenFailureMessage"/> is received.
  27. /// </summary>
  28. public event EventHandler<ChannelOpenFailedEventArgs> OpenFailed;
  29. /// <summary>
  30. /// Called when channel is opened by the server.
  31. /// </summary>
  32. /// <param name="remoteChannelNumber">The remote channel number.</param>
  33. /// <param name="initialWindowSize">Initial size of the window.</param>
  34. /// <param name="maximumPacketSize">Maximum size of the packet.</param>
  35. protected virtual void OnOpenConfirmation(uint remoteChannelNumber, uint initialWindowSize, uint maximumPacketSize)
  36. {
  37. InitializeRemoteInfo(remoteChannelNumber, initialWindowSize, maximumPacketSize);
  38. // Channel is consider to be open when confirmation message was received
  39. IsOpen = true;
  40. var openConfirmed = OpenConfirmed;
  41. if (openConfirmed != null)
  42. openConfirmed(this, new ChannelOpenConfirmedEventArgs(remoteChannelNumber, initialWindowSize, maximumPacketSize));
  43. }
  44. /// <summary>
  45. /// Send message to open a channel.
  46. /// </summary>
  47. /// <param name="message">Message to send</param>
  48. /// <exception cref="SshConnectionException">The client is not connected.</exception>
  49. /// <exception cref="SshOperationTimeoutException">The operation timed out.</exception>
  50. /// <exception cref="InvalidOperationException">The size of the packet exceeds the maximum size defined by the protocol.</exception>
  51. protected void SendMessage(ChannelOpenMessage message)
  52. {
  53. Session.SendMessage(message);
  54. }
  55. /// <summary>
  56. /// Called when channel failed to open.
  57. /// </summary>
  58. /// <param name="reasonCode">The reason code.</param>
  59. /// <param name="description">The description.</param>
  60. /// <param name="language">The language.</param>
  61. protected virtual void OnOpenFailure(uint reasonCode, string description, string language)
  62. {
  63. var openFailed = OpenFailed;
  64. if (openFailed != null)
  65. openFailed(this, new ChannelOpenFailedEventArgs(LocalChannelNumber, reasonCode, description, language));
  66. }
  67. private void OnChannelOpenConfirmation(object sender, MessageEventArgs<ChannelOpenConfirmationMessage> e)
  68. {
  69. if (e.Message.LocalChannelNumber == LocalChannelNumber)
  70. {
  71. try
  72. {
  73. OnOpenConfirmation(e.Message.RemoteChannelNumber, e.Message.InitialWindowSize,
  74. e.Message.MaximumPacketSize);
  75. }
  76. catch (Exception ex)
  77. {
  78. OnChannelException(ex);
  79. }
  80. }
  81. }
  82. private void OnChannelOpenFailure(object sender, MessageEventArgs<ChannelOpenFailureMessage> e)
  83. {
  84. if (e.Message.LocalChannelNumber == LocalChannelNumber)
  85. {
  86. try
  87. {
  88. OnOpenFailure(e.Message.ReasonCode, e.Message.Description, e.Message.Language);
  89. }
  90. catch (Exception ex)
  91. {
  92. OnChannelException(ex);
  93. }
  94. }
  95. }
  96. protected override void Dispose(bool disposing)
  97. {
  98. UnsubscribeFromSessionEvents(Session);
  99. base.Dispose(disposing);
  100. }
  101. /// <summary>
  102. /// Unsubscribes the current <see cref="ClientChannel"/> from session events.
  103. /// </summary>
  104. /// <param name="session">The session.</param>
  105. /// <remarks>
  106. /// Does nothing when <paramref name="session"/> is <c>null</c>.
  107. /// </remarks>
  108. private void UnsubscribeFromSessionEvents(ISession session)
  109. {
  110. if (session == null)
  111. return;
  112. session.ChannelOpenConfirmationReceived -= OnChannelOpenConfirmation;
  113. session.ChannelOpenFailureReceived -= OnChannelOpenFailure;
  114. }
  115. }
  116. }