src/vs/workbench/services/remote/common/remoteExplorerService.ts/TunnelModel/forward
class TunnelModel:	async forward(tunnelProperties: TunnelProperties, attributes?: Attributes | null): Promise<RemoteTunnel | void> {
		const existingTunnel = mapHasAddressLocalhostOrAllInterfaces(this.forwarded, tunnelProperties.remote.host, tunnelProperties.remote.port);
		attributes = attributes ??
			((attributes !== null)
				? (await this.getAttributes([tunnelProperties.remote]))?.get(tunnelProperties.remote.port)
				: undefined);
		const localPort = (tunnelProperties.local !== undefined) ? tunnelProperties.local : tunnelProperties.remote.port;

		if (!existingTunnel) {
			const authority = this.environmentService.remoteAuthority;
			const addressProvider: IAddressProvider | undefined = authority ? {
				getAddress: async () => { return (await this.remoteAuthorityResolverService.resolveAuthority(authority)).authority; }
			} : undefined;

			const key = makeAddress(tunnelProperties.remote.host, tunnelProperties.remote.port);
			this.inProgress.set(key, true);
			const tunnel = await this.tunnelService.openTunnel(addressProvider, tunnelProperties.remote.host, tunnelProperties.remote.port, localPort, (!tunnelProperties.elevateIfNeeded) ? attributes?.elevateIfNeeded : tunnelProperties.elevateIfNeeded, tunnelProperties.privacy, attributes?.protocol);
			if (tunnel && tunnel.localAddress) {
				const matchingCandidate = mapHasAddressLocalhostOrAllInterfaces<CandidatePort>(this._candidates ?? new Map(), tunnelProperties.remote.host, tunnelProperties.remote.port);
				const protocol = (tunnel.protocol ?
					((tunnel.protocol === TunnelProtocol.Https) ? TunnelProtocol.Https : TunnelProtocol.Http)
					: (attributes?.protocol ?? TunnelProtocol.Http));
				const newForward: Tunnel = {
					remoteHost: tunnel.tunnelRemoteHost,
					remotePort: tunnel.tunnelRemotePort,
					localPort: tunnel.tunnelLocalPort,
					name: attributes?.label ?? tunnelProperties.name,
					closeable: true,
					localAddress: tunnel.localAddress,
					protocol,
					localUri: await this.makeLocalUri(tunnel.localAddress, attributes),
					runningProcess: matchingCandidate?.detail,
					hasRunningProcess: !!matchingCandidate,
					pid: matchingCandidate?.pid,
					source: tunnelProperties.source ?? UserTunnelSource,
					privacy: tunnel.privacy,
				};
				this.forwarded.set(key, newForward);
				this.remoteTunnels.set(key, tunnel);
				this.inProgress.delete(key);
				await this.storeForwarded();
				await this.showPortMismatchModalIfNeeded(tunnel, localPort, attributes);
				this._onForwardPort.fire(newForward);
				return tunnel;
			}
		} else {
			const newName = attributes?.label ?? tunnelProperties.name;
			if (newName !== existingTunnel.name) {
				existingTunnel.name = newName;
				this._onForwardPort.fire();
			}
			if ((attributes?.protocol || (existingTunnel.protocol !== TunnelProtocol.Http)) && (attributes?.protocol !== existingTunnel.protocol)) {
				await this.close(existingTunnel.remoteHost, existingTunnel.remotePort);
				tunnelProperties.source = existingTunnel.source;
				await this.forward(tunnelProperties, attributes);
			}
			return mapHasAddressLocalhostOrAllInterfaces(this.remoteTunnels, tunnelProperties.remote.host, tunnelProperties.remote.port);
		}
	}