ForwardedPortLocal.NET.cs 3.3 KB

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