private void _StartServicePortForwardings()

in src/library/Connect/LocalEnvironmentManager.cs [358:418]


        private void _StartServicePortForwardings(
            EndpointInfo endpointInfo)
        {
            for (int i = 0; i < endpointInfo.Ports.Length; i++)
            {
                // TODO (lolodi): all this check should not be required since we already have mapped to ports that are not used (on linux/mac) or we did already blew up when we checked if the local port was free.
                if (_systemCheckResult != null)
                {
                    foreach (var serviceMessage in _systemCheckResult.ServiceMessages)
                    {
                        foreach (var p in serviceMessage.Ports)
                        {
                            if (p == endpointInfo.Ports[i].LocalPort)
                            {
                                _log.Info("Block StartServicePortForwardings due to bad service on port {0} {1}", p, serviceMessage.Message);
                                throw new InvalidUsageException(_operationContext, serviceMessage.Message);
                            }
                        }
                    }
                    foreach (var p in _systemCheckResult.PortBinding)
                    {
                        if (p.Key == endpointInfo.Ports[i].LocalPort)
                        {
                            var processPort = p.Key;
                            var processName = p.Value;
                            bool isSystemService = false;
                            if (processName.ToLowerInvariant().Contains("pid 4 can not obtain ownership information"))
                            {
                                processName = "PID 4 System Service";
                                isSystemService = true;
                            }

                            _log.Info("Block StartServicePortForwardings due to occupied port {0} {1}", processPort, processName);
                            if (isSystemService)
                            {
                                throw new InvalidUsageException(_operationContext, Resources.SystemProcessBindsOnPortFormat, processName, processPort, Product.Name);
                            }

                            throw new InvalidUsageException(_operationContext, Resources.ProcessBindsOnPortFormat, processName, processPort, Product.Name);
                        }
                    }
                }

                if (!this._portMappingManager.IsLocalPortAvailable(endpointInfo.LocalIP, endpointInfo.Ports[i].LocalPort))
                {
                    string additionalPortMessage = endpointInfo.Ports[i].LocalPort == 80 ? Resources.Port80WindowsServicesMessage : Resources.PortsInUseMessage;
                    throw new InvalidUsageException(_operationContext, Resources.PortInUseFormat, endpointInfo.Ports[i].LocalPort, additionalPortMessage);
                }
                // TODO (lolodi): Once we verify that we don't actually need the checks above we can just pass the whole enpoint to the _servicePortForwardManager and iterate thorugh all the ports there.
                var startInfo = new ServicePortForwardStartInfo
                {
                    ServiceDns = endpointInfo.DnsName,
                    ServicePort = endpointInfo.Ports[i].RemotePort,
                    LocalPort = endpointInfo.Ports[i].LocalPort,
                    IP = endpointInfo.LocalIP
                };

                this._servicePortForwardManager.Start(startInfo);
                this._ReportProgress(Resources.ServiceAvailableOnPortFormat, endpointInfo.DnsName, endpointInfo.LocalIP.ToString(), (this._useKubernetesServiceEnvironmentVariables || StringComparer.OrdinalIgnoreCase.Equals(endpointInfo.DnsName, DAPR)) ? endpointInfo.Ports[i].LocalPort : endpointInfo.Ports[i].RemotePort);
            }
        }