# < Summary

Information

Class: | Renci.SshNet.ForwardedPort
Assembly: | Renci.SshNet
File(s): | \home\appveyor\projects\ssh-net\src\Renci.SshNet\ForwardedPort.cs

Line coverage
100%

Covered lines: | 56
Uncovered lines: | 0
Coverable lines: | 56
Total lines: | 174
Line coverage: | 100%

Branch coverage
90%

Covered branches: | 18
Total branches: | 20
Branch coverage: | 90%

Method coverage

Feature is only available for sponsors

Upgrade to PRO version

# Metrics

Method | Branch coverage | Cyclomatic complexity | Line coverage
--- | --- | --- | ---
get_Session() | 100% | 1 | 100%
Start() | 100% | 6 | 100%
Stop() | 100% | 2 | 100%
Dispose() | 100% | 1 | 100%
StopPort(...) | 100% | 2 | 100%
Dispose(...) | 100% | 4 | 100%
RaiseExceptionEvent(...) | 50% | 2 | 100%
RaiseRequestReceived(...) | 50% | 2 | 100%
RaiseClosing() | 100% | 2 | 100%
Session_ErrorOccured(...) | 100% | 1 | 100%

# File(s)

## \home\appveyor\projects\ssh-net\src\Renci.SshNet\ForwardedPort.cs

| # | Line |  | Line coverage
--- | --- | --- | --- | ---
|  | `1` |  | `using System;`
|  | `2` |  | ``
|  | `3` |  | `using Renci.SshNet.Common;`
|  | `4` |  | ``
|  | `5` |  | `namespace Renci.SshNet`
|  | `6` |  | `{`
|  | `7` |  | `/// <summary>`
|  | `8` |  | `/// Base class for port forwarding functionality.`
|  | `9` |  | `/// </summary>`
|  | `10` |  | `public abstract class ForwardedPort : IForwardedPort`
|  | `11` |  | `{`
|  | `12` |  | `/// <summary>`
|  | `13` |  | `/// Gets or sets the session.`
|  | `14` |  | `/// </summary>`
|  | `15` |  | `/// <value>`
|  | `16` |  | `/// The session.`
|  | `17` |  | `/// </value>`
| 8067 | `18` |  | `internal ISession Session { get; set; }`
|  | `19` |  | ``
|  | `20` |  | `/// <summary>`
|  | `21` |  | `/// Gets a value indicating whether port forwarding is started.`
|  | `22` |  | `/// </summary>`
|  | `23` |  | `/// <value>`
|  | `24` |  | `/// <see langword="true"/> if port forwarding is started; otherwise, <see langword="false"/>.`
|  | `25` |  | `/// </value>`
|  | `26` |  | `public abstract bool IsStarted { get; }`
|  | `27` |  | ``
|  | `28` |  | `/// <summary>`
|  | `29` |  | `/// The <see cref="Closing"/> event occurs as the forwarded port is being stopped.`
|  | `30` |  | `/// </summary>`
|  | `31` |  | `public event EventHandler Closing;`
|  | `32` |  | ``
|  | `33` |  | `/// <summary>`
|  | `34` |  | `/// Occurs when an exception is thrown.`
|  | `35` |  | `/// </summary>`
|  | `36` |  | `public event EventHandler<ExceptionEventArgs> Exception;`
|  | `37` |  | ``
|  | `38` |  | `/// <summary>`
|  | `39` |  | `/// Occurs when a port forwarding request is received.`
|  | `40` |  | `/// </summary>`
|  | `41` |  | `public event EventHandler<PortForwardEventArgs> RequestReceived;`
|  | `42` |  | ``
|  | `43` |  | `/// <summary>`
|  | `44` |  | `/// Starts port forwarding.`
|  | `45` |  | `/// </summary>`
|  | `46` |  | `/// <exception cref="InvalidOperationException">The current <see cref="ForwardedPort"/> is already started -or-`
|  | `47` |  | `/// <exception cref="SshConnectionException">The client is not connected.</exception>`
|  | `48` |  | `public virtual void Start()`
| 687 | `49` |  | `{`
| 687 | `50` |  | `CheckDisposed();`
|  | `51` |  | ``
| 660 | `52` |  | `if (IsStarted)`
| 45 | `53` |  | `{`
| 45 | `54` |  | `throw new InvalidOperationException("Forwarded port is already started.");`
|  | `55` |  | `}`
|  | `56` |  | ``
| 615 | `57` |  | `if (Session is null)`
| 45 | `58` |  | `{`
| 45 | `59` |  | `throw new InvalidOperationException("Forwarded port is not added to a client.");`
|  | `60` |  | `}`
|  | `61` |  | ``
| 570 | `62` |  | `if (!Session.IsConnected)`
| 45 | `63` |  | `{`
| 45 | `64` |  | `throw new SshConnectionException("Client not connected.");`
|  | `65` |  | `}`
|  | `66` |  | ``
| 525 | `67` |  | `Session.ErrorOccured += Session_ErrorOccured;`
| 525 | `68` |  | `StartPort();`
| 525 | `69` |  | `}`
|  | `70` |  | ``
|  | `71` |  | `/// <summary>`
|  | `72` |  | `/// Stops port forwarding.`
|  | `73` |  | `/// </summary>`
|  | `74` |  | `#pragma warning disable CA1716 // Identifiers should not match keywords`
|  | `75` |  | `public virtual void Stop()`
|  | `76` |  | `#pragma warning restore CA1716 // Identifiers should not match keywords`
| 359 | `77` |  | `{`
| 359 | `78` |  | `if (IsStarted)`
| 252 | `79` |  | `{`
| 252 | `80` |  | `StopPort(Session.ConnectionInfo.Timeout);`
| 252 | `81` |  | `}`
| 359 | `82` |  | `}`
|  | `83` |  | ``
|  | `84` |  | `/// <summary>`
|  | `85` |  | `/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.`
|  | `86` |  | `/// </summary>`
|  | `87` |  | `public void Dispose()`
| 980 | `88` |  | `{`
| 980 | `89` |  | `Dispose(disposing: true);`
| 980 | `90` |  | `GC.SuppressFinalize(this);`
| 980 | `91` |  | `}`
|  | `92` |  | ``
|  | `93` |  | `/// <summary>`
|  | `94` |  | `/// Starts port forwarding.`
|  | `95` |  | `/// </summary>`
|  | `96` |  | `protected abstract void StartPort();`
|  | `97` |  | ``
|  | `98` |  | `/// <summary>`
|  | `99` |  | `/// Stops port forwarding, and waits for the specified timeout until all pending`
|  | `100` |  | `/// requests are processed.`
|  | `101` |  | `/// </summary>`
|  | `102` |  | `/// <param name="timeout">The maximum amount of time to wait for pending requests to finish processing.</param>`
|  | `103` |  | `protected virtual void StopPort(TimeSpan timeout)`
| 525 | `104` |  | `{`
| 525 | `105` |  | `RaiseClosing();`
|  | `106` |  | ``
| 525 | `107` |  | `var session = Session;`
| 525 | `108` |  | `if (session is not null)`
| 525 | `109` |  | `{`
| 525 | `110` |  | `session.ErrorOccured -= Session_ErrorOccured;`
| 525 | `111` |  | `}`
| 525 | `112` |  | `}`
|  | `113` |  | ``
|  | `114` |  | `/// <summary>`
|  | `115` |  | `/// Releases unmanaged and - optionally - managed resources.`
|  | `116` |  | `/// </summary>`
|  | `117` |  | `/// <param name="disposing"><see langowrd="true"/> to release both managed and unmanaged resources; <see langowr`
|  | `118` |  | `protected virtual void Dispose(bool disposing)`
| 744 | `119` |  | `{`
| 744 | `120` |  | `if (disposing)`
| 684 | `121` |  | `{`
| 684 | `122` |  | `var session = Session;`
| 684 | `123` |  | `if (session is not null)`
| 550 | `124` |  | `{`
| 550 | `125` |  | `StopPort(session.ConnectionInfo.Timeout);`
| 550 | `126` |  | `Session = null;`
| 550 | `127` |  | `}`
| 684 | `128` |  | `}`
| 744 | `129` |  | `}`
|  | `130` |  | ``
|  | `131` |  | `/// <summary>`
|  | `132` |  | `/// Ensures the current instance is not disposed.`
|  | `133` |  | `/// </summary>`
|  | `134` |  | `/// <exception cref="ObjectDisposedException">The current instance is disposed.</exception>`
|  | `135` |  | `protected abstract void CheckDisposed();`
|  | `136` |  | ``
|  | `137` |  | `/// <summary>`
|  | `138` |  | `/// Raises <see cref="Exception"/> event.`
|  | `139` |  | `/// </summary>`
|  | `140` |  | `/// <param name="exception">The exception.</param>`
|  | `141` |  | `protected void RaiseExceptionEvent(Exception exception)`
| 49 | `142` |  | `{`
| 49 | `143` |  | `Exception?.Invoke(this, new ExceptionEventArgs(exception));`
| 49 | `144` |  | `}`
|  | `145` |  | ``
|  | `146` |  | `/// <summary>`
|  | `147` |  | `/// Raises <see cref="RequestReceived"/> event.`
|  | `148` |  | `/// </summary>`
|  | `149` |  | `/// <param name="host">Request originator host.</param>`
|  | `150` |  | `/// <param name="port">Request originator port.</param>`
|  | `151` |  | `protected void RaiseRequestReceived(string host, uint port)`
| 207 | `152` |  | `{`
| 207 | `153` |  | `RequestReceived?.Invoke(this, new PortForwardEventArgs(host, port));`
| 207 | `154` |  | `}`
|  | `155` |  | ``
|  | `156` |  | `/// <summary>`
|  | `157` |  | `/// Raises the <see cref="IForwardedPort.Closing"/> event.`
|  | `158` |  | `/// </summary>`
|  | `159` |  | `private void RaiseClosing()`
| 525 | `160` |  | `{`
| 525 | `161` |  | `Closing?.Invoke(this, EventArgs.Empty);`
| 525 | `162` |  | `}`
|  | `163` |  | ``
|  | `164` |  | `/// <summary>`
|  | `165` |  | `/// Handles session ErrorOccured event.`
|  | `166` |  | `/// </summary>`
|  | `167` |  | `/// <param name="sender">The source of the event.</param>`
|  | `168` |  | `/// <param name="e">The <see cref="ExceptionEventArgs"/> instance containing the event data.</param>`
|  | `169` |  | `private void Session_ErrorOccured(object sender, ExceptionEventArgs e)`
| 27 | `170` |  | `{`
| 27 | `171` |  | `RaiseExceptionEvent(e.Exception);`
| 27 | `172` |  | `}`
|  | `173` |  | `}`
|  | `174` |  | `}`

# Methods/Properties

get_Session()
Start()
Stop()
Dispose()
StopPort(System.TimeSpan)
Dispose(System.Boolean)
RaiseExceptionEvent(System.Exception)
RaiseRequestReceived(System.String,System.UInt32)
RaiseClosing()
Session_ErrorOccured(System.Object,Renci.SshNet.Common.ExceptionEventArgs)