private void AddRoutingRules()

in src/common/IP/IPManager.cs [148:236]


        private void AddRoutingRules(IEnumerable<EndpointInfo> endpoints, CancellationToken cancellationToken)
        {
            if (_platform.IsWindows)
            {
                return;
            }

            using (var perfLogger =
                _log.StartPerformanceLogger(
                    Events.IP.AreaName,
                    Events.IP.Operations.AddRoutingRules))
            {
                if (_platform.IsOSX)
                {
                    // TODO: Fix Bug 1125798: Need to be a good pf citizen
                    StringBuilder inputBuilder = new StringBuilder();

                    foreach (var endpoint in endpoints)
                    {
                        if (endpoint.LocalIP.Equals(IPAddress.Loopback))
                        {
                            continue;
                        }
                        foreach (var portPair in endpoint.Ports)
                        {
                            inputBuilder.AppendLine($"rdr pass inet proto tcp from any to {endpoint.LocalIP} port {portPair.RemotePort} -> {endpoint.LocalIP} port {portPair.LocalPort}");
                        }
                    }

                    lock (_syncObject)
                    {
                        _log.Info("Updating routing table...");
                        (var exitCode, var output) = _platform.ExecuteAndReturnOutput(
                            command: "/sbin/pfctl",
                            arguments: "-ef -",
                            timeout: TimeSpan.FromSeconds(10),
                            stdOutCallback: (line) => _log.Verbose(line),
                            stdErrCallback: (line) => _log.Error(line),
                            processInput: inputBuilder.ToString());

                        var resultMessage = $"'/sbin/pfctl -ef - {inputBuilder}' returned exit code {exitCode}";
                        if (exitCode != 0)
                        {
                            _log.Warning(resultMessage);
                        }
                        else
                        {
                            _log.Info(resultMessage);
                        }
                        _log.Verbose($"All output: {output}");
                        perfLogger.SetSucceeded();
                    }
                }
                else if (_platform.IsLinux)
                {
                    var rules = new List<string>();
                    foreach (var endpoint in endpoints)
                    {
                        foreach (var portPair in endpoint.Ports)
                        {
                            // --wait        -w [seconds]    maximum wait to acquire xtables lock before give up
                            rules.Add($"--table nat --append PREROUTING -p tcp --dst {endpoint.LocalIP} --dport {portPair.RemotePort} --jump DNAT --to-destination {endpoint.LocalIP}:{portPair.LocalPort} --wait 30");
                            rules.Add($"--table nat --append OUTPUT -p tcp --dst {endpoint.LocalIP} --dport {portPair.RemotePort} --jump DNAT --to-destination {endpoint.LocalIP}:{portPair.LocalPort} --wait 30");
                        }
                    }

                    lock (_syncObject)
                    {
                        _log.Info("Adding rules to routing table...");
                        foreach (var rule in rules)
                        {
                            if (_linuxRoutingRules.Add(rule))
                            {
                                (var exitCode, var output) = RunUtility("iptables", rule, cancellationToken); // Only apply the rule if it wasn't previously present in the ruleset
                                if (exitCode != 0)
                                {
                                    throw new InvalidUsageException(_log.OperationContext, $"Running 'iptables' failed with exit code '{exitCode}': '{output}'");
                                }
                            }
                        }
                        perfLogger.SetSucceeded();
                    }
                }
                else
                {
                    throw new NotSupportedException("Unsupported platform");
                }
            }
        }