ForwardedPort
Base class for port forwarding functionality.
using Renci.SshNet.Common;
using System;
namespace Renci.SshNet
{
public abstract class ForwardedPort : IForwardedPort, IDisposable
{
internal ISession Session { get; set; }
public abstract bool IsStarted { get; }
public event EventHandler Closing;
public event EventHandler<ExceptionEventArgs> Exception;
public event EventHandler<PortForwardEventArgs> RequestReceived;
public virtual void Start()
{
CheckDisposed();
if (IsStarted)
throw new InvalidOperationException("Forwarded port is already started.");
if (Session == null)
throw new InvalidOperationException("Forwarded port is not added to a client.");
if (!Session.IsConnected)
throw new SshConnectionException("Client not connected.");
Session.ErrorOccured += Session_ErrorOccured;
StartPort();
}
public virtual void Stop()
{
if (IsStarted)
StopPort(Session.ConnectionInfo.Timeout);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected abstract void StartPort();
protected virtual void StopPort(TimeSpan timeout)
{
timeout.EnsureValidTimeout("timeout");
RaiseClosing();
ISession session = Session;
if (session != null)
session.ErrorOccured -= Session_ErrorOccured;
}
protected virtual void Dispose(bool disposing)
{
if (disposing) {
ISession session = Session;
if (session != null) {
StopPort(session.ConnectionInfo.Timeout);
Session = null;
}
}
}
protected abstract void CheckDisposed();
protected void RaiseExceptionEvent(Exception exception)
{
this.Exception?.Invoke(this, new ExceptionEventArgs(exception));
}
protected void RaiseRequestReceived(string host, uint port)
{
this.RequestReceived?.Invoke(this, new PortForwardEventArgs(host, port));
}
private void RaiseClosing()
{
this.Closing?.Invoke(this, EventArgs.Empty);
}
private void Session_ErrorOccured(object sender, ExceptionEventArgs e)
{
RaiseExceptionEvent(e.Exception);
}
}
}