ForwardedPortLocal.NET35.cs 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. using System;
  2. using System.Net.Sockets;
  3. using System.Net;
  4. using System.Threading;
  5. using Renci.SshNet.Channels;
  6. namespace Renci.SshNet
  7. {
  8. /// <summary>
  9. /// Provides functionality for local port forwarding
  10. /// </summary>
  11. public partial class ForwardedPortLocal
  12. {
  13. private TcpListener _listener;
  14. partial void ExecuteThread(Action action)
  15. {
  16. ThreadPool.QueueUserWorkItem((o) => { action(); });
  17. }
  18. partial void InternalStart()
  19. {
  20. // If port already started don't start it again
  21. if (this.IsStarted)
  22. return;
  23. var ep = new IPEndPoint(Dns.GetHostAddresses(this.BoundHost)[0], (int)this.BoundPort);
  24. this._listener = new TcpListener(ep);
  25. this._listener.Start();
  26. this._listenerTaskCompleted = new ManualResetEvent(false);
  27. this.ExecuteThread(() =>
  28. {
  29. try
  30. {
  31. while (true)
  32. {
  33. var socket = this._listener.AcceptSocket();
  34. this.ExecuteThread(() =>
  35. {
  36. try
  37. {
  38. IPEndPoint originatorEndPoint = socket.RemoteEndPoint as IPEndPoint;
  39. this.RaiseRequestReceived(originatorEndPoint.Address.ToString(), (uint)originatorEndPoint.Port);
  40. var channel = this.Session.CreateChannel<ChannelDirectTcpip>();
  41. channel.Bind(this.Host, this.Port, socket);
  42. }
  43. catch (Exception exp)
  44. {
  45. this.RaiseExceptionEvent(exp);
  46. }
  47. });
  48. }
  49. }
  50. catch (SocketException exp)
  51. {
  52. if (!(exp.SocketErrorCode == SocketError.Interrupted))
  53. {
  54. this.RaiseExceptionEvent(exp);
  55. }
  56. }
  57. catch (Exception exp)
  58. {
  59. this.RaiseExceptionEvent(exp);
  60. }
  61. finally
  62. {
  63. this._listenerTaskCompleted.Set();
  64. }
  65. });
  66. this.IsStarted = true;
  67. }
  68. partial void InternalStop()
  69. {
  70. // If port not started you cant stop it
  71. if (!this.IsStarted)
  72. return;
  73. this._listener.Stop();
  74. this._listenerTaskCompleted.WaitOne(this.Session.ConnectionInfo.Timeout);
  75. this._listenerTaskCompleted.Dispose();
  76. this._listenerTaskCompleted = null;
  77. this.IsStarted = false;
  78. }
  79. }
  80. }