Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add remote port parameter to TCP listener factory #104

Merged
merged 2 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/cs/Ssh.Tcp/DefaultTcpListenerFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ internal class DefaultTcpListenerFactory : ITcpListenerFactory
{
/// <inheritdoc />
public Task<TcpListener> CreateTcpListenerAsync(
int? remotePort,
IPAddress localIPAddress,
int localPort,
bool canChangePort,
bool canChangeLocalPort,
TraceSource trace,
CancellationToken cancellation)
{
Expand Down
9 changes: 6 additions & 3 deletions src/cs/Ssh.Tcp/ITcpListenerFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ public interface ITcpListenerFactory
/// Creates and starts a TCP listener for the specified local network address and port
/// number.
/// </summary>
/// <param name="remotePort">The remote port that this local port will connect to (if known).
/// </param>
/// <param name="localIPAddress">Local IP address to listen on.</param>
/// <param name="localPort">Requested local port to listen on, or 0 to use a random
/// available port number.</param>
/// <param name="canChangePort">True if the factory is allowed to select a different
/// port number than the one that was requested; if false then the factory must either
/// <param name="canChangeLocalPort">True if the factory is allowed to select a different
/// local port number than the one that was requested; if false then the factory must either
/// use the requested port or throw an exception.</param>
/// <param name="trace">Trace source.</param>
/// <param name="cancellation">Cancellation token.</param>
Expand All @@ -43,9 +45,10 @@ public interface ITcpListenerFactory
/// <see cref="TcpListener.LocalEndpoint"/> property.
/// </remarks>
Task<TcpListener> CreateTcpListenerAsync(
int? remotePort,
IPAddress localIPAddress,
int localPort,
bool canChangePort,
bool canChangeLocalPort,
TraceSource trace,
CancellationToken cancellation);
}
16 changes: 12 additions & 4 deletions src/cs/Ssh.Tcp/Services/LocalPortForwarder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,12 @@ internal async Task StartForwardingAsync(CancellationToken cancellation)
{
var trace = this.pfs.Session.Trace;
this.listener = await this.pfs.TcpListenerFactory.CreateTcpListenerAsync(
listenAddress, LocalPort, canChangePort: true, trace, cancellation)
.ConfigureAwait(false);
RemotePort,
listenAddress,
LocalPort,
canChangeLocalPort: true,
trace,
cancellation).ConfigureAwait(false);

LocalPort = ((IPEndPoint)this.listener.LocalEndpoint).Port;

Expand All @@ -94,8 +98,12 @@ internal async Task StartForwardingAsync(CancellationToken cancellation)
try
{
this.listener2 = await this.pfs.TcpListenerFactory.CreateTcpListenerAsync(
listenAddress, LocalPort, canChangePort: false, trace, cancellation)
.ConfigureAwait(false);
RemotePort,
listenAddress,
LocalPort,
canChangeLocalPort: false,
trace,
cancellation).ConfigureAwait(false);
}
catch (SocketException sockex)
when (sockex.SocketErrorCode == SocketError.AddressNotAvailable)
Expand Down
3 changes: 2 additions & 1 deletion src/cs/Ssh.Tcp/SshServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,10 @@ public async Task AcceptSessionsAsync(
try
{
listener = await TcpListenerFactory.CreateTcpListenerAsync(
remotePort: null,
localAddress,
localPort,
canChangePort: false,
canChangeLocalPort: false,
this.trace,
CancellationToken.None)
.ConfigureAwait(false);
Expand Down
2 changes: 2 additions & 0 deletions src/ts/ssh-tcp/services/localPortForwarder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export class LocalPortForwarder extends SshService {
let listenAddress = this.localIPAddress;
try {
this.tcpListener = await this.pfs.tcpListenerFactory.createTcpListener(
this.remotePort,
listenAddress,
this.port,
true,
Expand All @@ -97,6 +98,7 @@ export class LocalPortForwarder extends SshService {
listenAddress = this.localIPAddress === '0.0.0.0' ? '::' : '::1';
try {
this.tcpListener2 = await this.pfs.tcpListenerFactory.createTcpListener(
this.remotePort,
listenAddress,
this.port,
false,
Expand Down
1 change: 1 addition & 0 deletions src/ts/ssh-tcp/sshServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export class SshServer implements Disposable {

try {
this.tcpListener = await this.tcpListenerFactory.createTcpListener(
undefined, // remotePort
localAddress,
localPort,
false,
Expand Down
7 changes: 5 additions & 2 deletions src/ts/ssh-tcp/tcpListenerFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ export interface TcpListenerFactory {
* Creates and starts a TCP listener for the specified local network address and port
* number.
*
* @param remotePort The remote port that this local port will connect to (if known).
* @param localIPAddress Local IP address to listen on.
* @param localPort Requested local port to listen on, or 0 to use a random
* available port number.
* @param canChangePort True if the factory is allowed to select a different
* port number than the one that was requested; if false then the factory must either
* @param canChangeLocalPort True if the factory is allowed to select a different
jasongin marked this conversation as resolved.
Show resolved Hide resolved
* local port number than the one that was requested; if false then the factory must either
* use the requested port or throw an exception.</param>
* @param cancellation">Cancellation token.</param>
* @returns TCP listener object that has started listening.</returns>
Expand All @@ -33,6 +34,7 @@ export interface TcpListenerFactory {
* obtain the actual port from the returned listener's `localEndpoint` property.
*/
createTcpListener(
remotePort: number | undefined,
localIPAddress: string,
localPort: number,
canChangePort: boolean,
Expand All @@ -42,6 +44,7 @@ export interface TcpListenerFactory {

export class DefaultTcpListenerFactory implements TcpListenerFactory {
public async createTcpListener(
remotePort: number | undefined,
localIPAddress: string,
localPort: number,
canChangePort: boolean,
Expand Down
1 change: 1 addition & 0 deletions test/cs/Ssh.Test/PortForwardingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ public TestTcpListenerFactory(int localPortOverride, bool autoIncrement = false)
}

public Task<TcpListener> CreateTcpListenerAsync(
int? remotePort,
IPAddress localIPAddress,
int localPort,
bool canChangePort,
Expand Down
1 change: 1 addition & 0 deletions test/ts/ssh-test/portForwardingTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class TestTcpListenerFactory implements TcpListenerFactory {
public constructor(public readonly localPortOverride: number) { }

public async createTcpListener(
remotePort: number | undefined,
localIPAddress: string,
localPort: number,
canChangePort: boolean,
Expand Down
2 changes: 1 addition & 1 deletion version.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "https://raw.githubusercontent.com/AArnott/Nerdbank.GitVersioning/main/src/NerdBank.GitVersioning/version.schema.json",
"version": "3.11",
"version": "3.12",
"publicReleaseRefSpec": [
"^refs/heads/main$",
"^refs/heads/releases/.+$"
Expand Down
Loading