private void ReloadWait() { if (_port_map_listener != null) { foreach (Listener l in _port_map_listener) { l.Stop(); } _port_map_listener = null; } // some logic in configuration updated the config when saving, we need to read it again _config = MergeGetConfiguration(_config); _config.FlushPortMapCache(); _rangeSet = new IPRangeSet(); _rangeSet.TouchChnIpFile(null); _rangeSet.LoadChn(); if (_config.proxyRuleMode == (int)ProxyRuleMode.BypassLanAndNotChina) { _rangeSet.Reverse(); } if (polipoRunner == null) { polipoRunner = new HttpProxyRunner(); } bool _firstRun = firstRun; for (int i = 1; i <= 5; ++i) { _firstRun = false; try { if (_listener != null && !_listener.isConfigChange(_config)) { Local local = new Local(_config, _transfer, _rangeSet); _listener.GetServices()[0] = local; if (polipoRunner.HasExited()) { polipoRunner.Stop(); polipoRunner.Start(_config); _listener.GetServices()[3] = new HttpPortForwarder(polipoRunner.RunningPort, _config); } } else { if (_listener != null) { _listener.Stop(); _listener = null; } polipoRunner.Stop(); polipoRunner.Start(_config); List <Listener.IService> services = new List <Listener.IService> { new Local(_config, _transfer, _rangeSet), new HttpPortForwarder(polipoRunner.RunningPort, _config) }; _listener = new Listener(services); _listener.Start(_config, 0); } break; } catch (Exception e) { // translate Microsoft language into human language // i.e. An attempt was made to access a socket in a way forbidden by its access permissions => Port already in use if (e is SocketException se) { if (se.SocketErrorCode == SocketError.AccessDenied) { e = new Exception(I18N.GetString("Port already in use") + string.Format(" {0}", _config.localPort), e); } } Logging.LogUsefulException(e); if (!_firstRun) { ReportError(e); break; } else { Thread.Sleep(1000 * i * i); } if (_listener != null) { _listener.Stop(); _listener = null; } } } _port_map_listener = new List <Listener>(); foreach (KeyValuePair <int, PortMapConfigCache> pair in _config.GetPortMapCache()) { try { Local local = new Local(_config, _transfer, _rangeSet); List <Listener.IService> services = new List <Listener.IService>(); services.Add(local); Listener listener = new Listener(services); listener.Start(_config, pair.Key); _port_map_listener.Add(listener); } catch (Exception e) { // translate Microsoft language into human language // i.e. An attempt was made to access a socket in a way forbidden by its access permissions => Port already in use if (e is SocketException se) { if (se.SocketErrorCode == SocketError.AccessDenied) { e = new Exception(I18N.GetString("Port already in use") + string.Format(" {0}", pair.Key), e); } } Logging.LogUsefulException(e); ReportError(e); } } ConfigChanged?.Invoke(this, new EventArgs()); SystemProxy.Update(_config, false); Util.Utils.ReleaseMemory(); }