2
0

ClientChannel.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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 instance of the <see cref="ClientChannel"/> class.
  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. OpenConfirmed?.Invoke(this, new ChannelOpenConfirmedEventArgs(remoteChannelNumber, initialWindowSize, maximumPacketSize));
  41. }
  42. /// <summary>
  43. /// Send message to open a channel.
  44. /// </summary>
  45. /// <param name="message">Message to send.</param>
  46. /// <exception cref="SshConnectionException">The client is not connected.</exception>
  47. /// <exception cref="SshOperationTimeoutException">The operation timed out.</exception>
  48. /// <exception cref="InvalidOperationException">The size of the packet exceeds the maximum size defined by the protocol.</exception>
  49. protected void SendMessage(ChannelOpenMessage message)
  50. {
  51. Session.SendMessage(message);
  52. }
  53. /// <summary>
  54. /// Called when channel failed to open.
  55. /// </summary>
  56. /// <param name="reasonCode">The reason code.</param>
  57. /// <param name="description">The description.</param>
  58. /// <param name="language">The language.</param>
  59. protected virtual void OnOpenFailure(uint reasonCode, string description, string language)
  60. {
  61. OpenFailed?.Invoke(this, new ChannelOpenFailedEventArgs(LocalChannelNumber, reasonCode, description, language));
  62. }
  63. private void OnChannelOpenConfirmation(object sender, MessageEventArgs<ChannelOpenConfirmationMessage> e)
  64. {
  65. if (e.Message.LocalChannelNumber == LocalChannelNumber)
  66. {
  67. try
  68. {
  69. OnOpenConfirmation(e.Message.RemoteChannelNumber,
  70. e.Message.InitialWindowSize,
  71. e.Message.MaximumPacketSize);
  72. }
  73. catch (Exception ex)
  74. {
  75. OnChannelException(ex);
  76. }
  77. }
  78. }
  79. private void OnChannelOpenFailure(object sender, MessageEventArgs<ChannelOpenFailureMessage> e)
  80. {
  81. if (e.Message.LocalChannelNumber == LocalChannelNumber)
  82. {
  83. try
  84. {
  85. OnOpenFailure(e.Message.ReasonCode, e.Message.Description, e.Message.Language);
  86. }
  87. catch (Exception ex)
  88. {
  89. OnChannelException(ex);
  90. }
  91. }
  92. }
  93. protected override void Dispose(bool disposing)
  94. {
  95. UnsubscribeFromSessionEvents(Session);
  96. base.Dispose(disposing);
  97. }
  98. /// <summary>
  99. /// Unsubscribes the current <see cref="ClientChannel"/> from session events.
  100. /// </summary>
  101. /// <param name="session">The session.</param>
  102. /// <remarks>
  103. /// Does nothing when <paramref name="session"/> is <see langword="null"/>.
  104. /// </remarks>
  105. private void UnsubscribeFromSessionEvents(ISession session)
  106. {
  107. if (session is null)
  108. {
  109. return;
  110. }
  111. session.ChannelOpenConfirmationReceived -= OnChannelOpenConfirmation;
  112. session.ChannelOpenFailureReceived -= OnChannelOpenFailure;
  113. }
  114. }
  115. }