Skip to content

Commit b09701a

Browse files
authored
Fix duplicate port forwarding for statically forwarded ports (microsoft#163899)
* Fix duplicate port in view * Include localhost address when resolving external
1 parent 5857465 commit b09701a

File tree

3 files changed

+20
-2
lines changed

3 files changed

+20
-2
lines changed

src/vs/platform/tunnel/common/tunnel.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ export interface ITunnelService {
126126

127127
canTunnel(uri: URI): boolean;
128128
openTunnel(addressProvider: IAddressProvider | undefined, remoteHost: string | undefined, remotePort: number, localPort?: number, elevateIfNeeded?: boolean, privacy?: string, protocol?: string): Promise<RemoteTunnel | undefined> | undefined;
129+
getExistingTunnel(remoteHost: string, remotePort: number): Promise<RemoteTunnel | undefined>;
129130
setEnvironmentTunnel(remoteHost: string, remotePort: number, localAddress: string, privacy: string, protocol: string): void;
130131
closeTunnel(remoteHost: string, remotePort: number): Promise<void>;
131132
setTunnelProvider(provider: ITunnelProvider | undefined): IDisposable;
@@ -282,6 +283,19 @@ export abstract class AbstractTunnelService implements ITunnelService {
282283
}));
283284
}
284285

286+
async getExistingTunnel(remoteHost: string, remotePort: number): Promise<RemoteTunnel | undefined> {
287+
if (isAllInterfaces(remoteHost) || isLocalhost(remoteHost)) {
288+
remoteHost = LOCALHOST_ADDRESSES[0];
289+
}
290+
291+
const existing = this.getTunnelFromMap(remoteHost, remotePort);
292+
if (existing) {
293+
++existing.refcount;
294+
return existing.value;
295+
}
296+
return undefined;
297+
}
298+
285299
openTunnel(addressProvider: IAddressProvider | undefined, remoteHost: string | undefined, remotePort: number, localPort?: number, elevateIfNeeded: boolean = false, privacy?: string, protocol?: string): Promise<RemoteTunnel | undefined> | undefined {
286300
this.logService.trace(`ForwardedPorts: (TunnelService) openTunnel request for ${remoteHost}:${remotePort} on local port ${localPort}.`);
287301
if (!addressProvider) {

src/vs/workbench/electron-sandbox/window.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -769,13 +769,16 @@ export class NativeWindow extends Disposable {
769769
return (await this.remoteAuthorityResolverService.resolveAuthority(remoteAuthority)).authority;
770770
}
771771
} : undefined;
772-
const tunnel = await this.tunnelService.openTunnel(addressProvider, portMappingRequest.address, portMappingRequest.port);
772+
let tunnel = await this.tunnelService.getExistingTunnel(portMappingRequest.address, portMappingRequest.port);
773+
if (!tunnel) {
774+
tunnel = await this.tunnelService.openTunnel(addressProvider, portMappingRequest.address, portMappingRequest.port);
775+
}
773776
if (tunnel) {
774777
const addressAsUri = URI.parse(tunnel.localAddress);
775778
const resolved = addressAsUri.scheme.startsWith(uri.scheme) ? addressAsUri : uri.with({ authority: tunnel.localAddress });
776779
return {
777780
resolved,
778-
dispose: () => tunnel.dispose(),
781+
dispose: () => tunnel?.dispose(),
779782
};
780783
}
781784
}

src/vs/workbench/services/remote/common/remoteExplorerService.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,7 @@ export class TunnelModel extends Disposable {
473473
this._register(this.tunnelService.onTunnelOpened(async (tunnel) => {
474474
const key = makeAddress(tunnel.tunnelRemoteHost, tunnel.tunnelRemotePort);
475475
if (!mapHasAddressLocalhostOrAllInterfaces(this.forwarded, tunnel.tunnelRemoteHost, tunnel.tunnelRemotePort)
476+
&& !mapHasAddressLocalhostOrAllInterfaces(this.detected, tunnel.tunnelRemoteHost, tunnel.tunnelRemotePort)
476477
&& !mapHasAddressLocalhostOrAllInterfaces(this.inProgress, tunnel.tunnelRemoteHost, tunnel.tunnelRemotePort)
477478
&& tunnel.localAddress) {
478479
const matchingCandidate = mapHasAddressLocalhostOrAllInterfaces(this._candidates ?? new Map(), tunnel.tunnelRemoteHost, tunnel.tunnelRemotePort);

0 commit comments

Comments
 (0)