ForwardedPortLocal.NET40.cs 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. using System.Threading.Tasks;
  2. using System;
  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. partial void ExecuteThread(Action action)
  16. {
  17. Task.Factory.StartNew(action);
  18. }
  19. partial void InternalStart()
  20. {
  21. // If port already started don't start it again
  22. if (this.IsStarted)
  23. return;
  24. var ep = new IPEndPoint(Dns.GetHostAddresses(this.BoundHost)[0], (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. var socket = this._listener.AcceptSocket();
  35. this.ExecuteThread(() =>
  36. {
  37. try
  38. {
  39. IPEndPoint originatorEndPoint = socket.RemoteEndPoint as IPEndPoint;
  40. this.RaiseRequestReceived(originatorEndPoint.Address.ToString(), (uint)originatorEndPoint.Port);
  41. var channel = this.Session.CreateChannel<ChannelDirectTcpip>();
  42. channel.Bind(this.Host, this.Port, socket);
  43. }
  44. catch (Exception exp)
  45. {
  46. this.RaiseExceptionEvent(exp);
  47. }
  48. });
  49. }
  50. }
  51. catch (SocketException exp)
  52. {
  53. if (!(exp.SocketErrorCode == SocketError.Interrupted))
  54. {
  55. this.RaiseExceptionEvent(exp);
  56. }
  57. }
  58. catch (Exception exp)
  59. {
  60. this.RaiseExceptionEvent(exp);
  61. }
  62. finally
  63. {
  64. this._listenerTaskCompleted.Set();
  65. }
  66. });
  67. this.IsStarted = true;
  68. }
  69. partial void InternalStop()
  70. {
  71. // If port not started you cant stop it
  72. if (!this.IsStarted)
  73. return;
  74. this._listener.Stop();
  75. this._listenerTaskCompleted.WaitOne(this.Session.ConnectionInfo.Timeout);
  76. this._listenerTaskCompleted.Dispose();
  77. this._listenerTaskCompleted = null;
  78. this.IsStarted = false;
  79. }
  80. }
  81. }