Fix duplicate port forwarding for statically forwarded ports (#163899)

* Fix duplicate port in view

* Include localhost address when resolving external
This commit is contained in:
Alex Ross
2022-10-18 20:08:21 +02:00
committed by GitHub
parent 58574650b6
commit b09701ac1b
3 changed files with 20 additions and 2 deletions

View File

@@ -126,6 +126,7 @@ export interface ITunnelService {
canTunnel(uri: URI): boolean;
openTunnel(addressProvider: IAddressProvider | undefined, remoteHost: string | undefined, remotePort: number, localPort?: number, elevateIfNeeded?: boolean, privacy?: string, protocol?: string): Promise<RemoteTunnel | undefined> | undefined;
getExistingTunnel(remoteHost: string, remotePort: number): Promise<RemoteTunnel | undefined>;
setEnvironmentTunnel(remoteHost: string, remotePort: number, localAddress: string, privacy: string, protocol: string): void;
closeTunnel(remoteHost: string, remotePort: number): Promise<void>;
setTunnelProvider(provider: ITunnelProvider | undefined): IDisposable;
@@ -282,6 +283,19 @@ export abstract class AbstractTunnelService implements ITunnelService {
}));
}
async getExistingTunnel(remoteHost: string, remotePort: number): Promise<RemoteTunnel | undefined> {
if (isAllInterfaces(remoteHost) || isLocalhost(remoteHost)) {
remoteHost = LOCALHOST_ADDRESSES[0];
}
const existing = this.getTunnelFromMap(remoteHost, remotePort);
if (existing) {
++existing.refcount;
return existing.value;
}
return undefined;
}
openTunnel(addressProvider: IAddressProvider | undefined, remoteHost: string | undefined, remotePort: number, localPort?: number, elevateIfNeeded: boolean = false, privacy?: string, protocol?: string): Promise<RemoteTunnel | undefined> | undefined {
this.logService.trace(`ForwardedPorts: (TunnelService) openTunnel request for ${remoteHost}:${remotePort} on local port ${localPort}.`);
if (!addressProvider) {

View File

@@ -769,13 +769,16 @@ export class NativeWindow extends Disposable {
return (await this.remoteAuthorityResolverService.resolveAuthority(remoteAuthority)).authority;
}
} : undefined;
const tunnel = await this.tunnelService.openTunnel(addressProvider, portMappingRequest.address, portMappingRequest.port);
let tunnel = await this.tunnelService.getExistingTunnel(portMappingRequest.address, portMappingRequest.port);
if (!tunnel) {
tunnel = await this.tunnelService.openTunnel(addressProvider, portMappingRequest.address, portMappingRequest.port);
}
if (tunnel) {
const addressAsUri = URI.parse(tunnel.localAddress);
const resolved = addressAsUri.scheme.startsWith(uri.scheme) ? addressAsUri : uri.with({ authority: tunnel.localAddress });
return {
resolved,
dispose: () => tunnel.dispose(),
dispose: () => tunnel?.dispose(),
};
}
}

View File

@@ -473,6 +473,7 @@ export class TunnelModel extends Disposable {
this._register(this.tunnelService.onTunnelOpened(async (tunnel) => {
const key = makeAddress(tunnel.tunnelRemoteHost, tunnel.tunnelRemotePort);
if (!mapHasAddressLocalhostOrAllInterfaces(this.forwarded, tunnel.tunnelRemoteHost, tunnel.tunnelRemotePort)
&& !mapHasAddressLocalhostOrAllInterfaces(this.detected, tunnel.tunnelRemoteHost, tunnel.tunnelRemotePort)
&& !mapHasAddressLocalhostOrAllInterfaces(this.inProgress, tunnel.tunnelRemoteHost, tunnel.tunnelRemotePort)
&& tunnel.localAddress) {
const matchingCandidate = mapHasAddressLocalhostOrAllInterfaces(this._candidates ?? new Map(), tunnel.tunnelRemoteHost, tunnel.tunnelRemotePort);