Skip to content

Commit

Permalink
Fix host port number in TCP listener factory (#485)
Browse files Browse the repository at this point in the history
  • Loading branch information
jasongin authored Sep 27, 2024
1 parent 87c585c commit 106b4e9
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 24 deletions.
2 changes: 1 addition & 1 deletion cs/build/build.props
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
<ReportGeneratorVersion>4.8.13</ReportGeneratorVersion>
<SystemTextEncodingsWebPackageVersion>4.7.2</SystemTextEncodingsWebPackageVersion>
<VisualStudioValidationVersion>15.5.31</VisualStudioValidationVersion>
<DevTunnelsSshPackageVersion>3.11.41</DevTunnelsSshPackageVersion>
<DevTunnelsSshPackageVersion>3.12.5</DevTunnelsSshPackageVersion>
<XunitRunnerVisualStudioVersion>2.4.0</XunitRunnerVisualStudioVersion>
<XunitVersion>2.4.0</XunitVersion>
</PropertyGroup>
Expand Down
12 changes: 8 additions & 4 deletions cs/src/Connections/RetryTcpListenerFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ public RetryTcpListenerFactory(IPAddress localAddress)

/// <inheritdoc />
public Task<TcpListener> CreateTcpListenerAsync(
int? remotePort,
IPAddress localIPAddress,
int localPort,
bool canChangePort,
bool canChangeLocalPort,
TraceSource trace,
CancellationToken cancellation)
{
Expand Down Expand Up @@ -77,14 +78,17 @@ public Task<TcpListener> CreateTcpListenerAsync(

listener.Start();

// It is assumed that the localPort passed in is the same as the host port
trace.TraceInformation($"Forwarding from {listener.LocalEndpoint} to host port {localPort}.");
if (remotePort != null)
{
trace.TraceInformation($"Forwarding from {listener.LocalEndpoint} to host port {remotePort}.");
}

return Task.FromResult(listener);
}
catch (SocketException sockex)
when ((sockex.SocketErrorCode == SocketError.AccessDenied ||
sockex.SocketErrorCode == SocketError.AddressAlreadyInUse) &&
offset < maxOffet && canChangePort)
offset < maxOffet && canChangeLocalPort)
{
trace.TraceEvent(TraceEventType.Verbose, 1, "Listening on port " + localPortNumber + " failed: " + sockex.Message);
trace.TraceEvent(TraceEventType.Verbose, 2, "Incrementing port and trying again");
Expand Down
18 changes: 9 additions & 9 deletions ts/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions ts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
"build-pack-publish": "npm run build && npm run pack && npm run publish"
},
"dependencies": {
"@microsoft/dev-tunnels-ssh": "^3.11.36",
"@microsoft/dev-tunnels-ssh-tcp": "^3.11.36",
"@microsoft/dev-tunnels-ssh": "^3.12.5",
"@microsoft/dev-tunnels-ssh-tcp": "^3.12.5",
"await-semaphore": "^0.1.3",
"axios": "^1.6.6",
"buffer": "^5.2.1",
Expand Down
4 changes: 2 additions & 2 deletions ts/src/connections/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
"vscode-jsonrpc": "^4.0.0",
"@microsoft/dev-tunnels-contracts": ">1.1.37",
"@microsoft/dev-tunnels-management": ">1.1.37",
"@microsoft/dev-tunnels-ssh": "^3.11.36",
"@microsoft/dev-tunnels-ssh-tcp": "^3.11.36",
"@microsoft/dev-tunnels-ssh": "^3.12.5",
"@microsoft/dev-tunnels-ssh-tcp": "^3.12.5",
"uuid": "^3.3.3",
"await-semaphore": "^0.1.3",
"websocket": "^1.0.28",
Expand Down
22 changes: 16 additions & 6 deletions ts/src/connections/retryTcpListenerFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ export class RetryTcpListenerFactory implements TcpListenerFactory {
public constructor(public readonly localAddress: string) {}

public async createTcpListener(
remotePort: number | undefined,
localIPAddress: string,
localPort: number,
canChangePort: boolean,
canChangeLocalPort: boolean,
cancellation?: CancellationToken,
): Promise<Server> {
// The SSH protocol may specify a local IP address for forwarding, but that is ignored
Expand All @@ -33,12 +34,12 @@ export class RetryTcpListenerFactory implements TcpListenerFactory {
localIPAddress = this.localAddress;
}

const maxOffet = 10;
const maxOffset = 10;
const listener = net.createServer();

for (let offset = 0; ; offset++) {
// After reaching the max offset, pass 0 to pick a random available port.
const localPortNumber = offset === maxOffet ? 0 : localPort + offset;
const localPortNumber = offset === maxOffset ? 0 : localPort + offset;

try {
return await new Promise<Server>((resolve, reject) => {
Expand All @@ -48,16 +49,25 @@ export class RetryTcpListenerFactory implements TcpListenerFactory {
ipv6Only: net.isIPv6(localIPAddress),
});
listener.on('listening', () => {
if (remotePort) {
const { address, port } = <net.AddressInfo>listener.address();
console.log(`Forwarding from ${address}:${port} to host port ${remotePort}.`);
}

resolve(listener);
});
listener.on('error', (err) => {
reject(err);
});
});
} catch (err) {
console.log('Listening on port ' + localPortNumber + ' failed: ' + err);
console.log('Incrementing port and trying again');
continue;
if (offset < maxOffset && canChangeLocalPort) {
console.log('Listening on port ' + localPortNumber + ' failed: ' + err);
console.log('Incrementing port and trying again');
continue;
} else {
throw err;
}
}
}
}
Expand Down

0 comments on commit 106b4e9

Please sign in to comment.