private void Reload() { if (_port_map_listener != null) { foreach (var 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(); Logging.save_to_file = _config.logEnable; Logging.OpenLogFile(); ReloadIPRange(); var hostMap = new HostMap(); hostMap.LoadHostFile(); HostMap.Instance().Clear(hostMap); if (privoxyRunner == null) { privoxyRunner = new HttpProxyRunner(); } if (_pacServer == null) { _pacServer = new PACServer(); _pacServer.PACFileChanged += pacServer_PACFileChanged; _pacServer.UserRuleFileChanged += pacServer_UserRuleFileChanged; } _pacServer.UpdateConfiguration(_config); if (gfwListUpdater == null) { gfwListUpdater = new GFWListUpdater(); gfwListUpdater.UpdateCompleted += pacServer_PACUpdateCompleted; gfwListUpdater.Error += pacServer_PACUpdateError; } if (chnDomainsAndIPUpdater == null) { chnDomainsAndIPUpdater = new ChnDomainsAndIPUpdater(); chnDomainsAndIPUpdater.UpdateCompleted += pacServer_PACUpdateCompleted; chnDomainsAndIPUpdater.Error += pacServer_PACUpdateError; } _listener?.Stop(); // don't put PrivoxyRunner.Start() before pacServer.Stop() // or bind will fail when switching bind address from 0.0.0.0 to 127.0.0.1 // though UseShellExecute is set to true now // http://stackoverflow.com/questions/10235093/socket-doesnt-close-after-application-exits-if-a-launched-process-is-open try { privoxyRunner.Stop(); privoxyRunner.Start(_config); var local = new Local(_config, _transfer, _rangeSet); var services = new List <Listener.Service> { local, _pacServer, new APIServer(this, _config), new HttpPortForwarder(privoxyRunner.RunningPort, _config) }; _listener = new Listener(services); _listener.Start(_config, 0); } 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.AddressAlreadyInUse) { e = new Exception(string.Format(I18N.GetString("Port {0} already in use"), _config.localPort), se); } else if (se.SocketErrorCode == SocketError.AccessDenied) { e = new Exception(string.Format(I18N.GetString("Port {0} is reserved by system"), _config.localPort), se); } } Logging.LogUsefulException(e); ReportError(e); } _port_map_listener = new List <Listener>(); foreach (var pair in _config.GetPortMapCache()) { try { var local = new Local(_config, _transfer, _rangeSet); var services = new List <Listener.Service> { local }; var 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.AddressAlreadyInUse) { e = new Exception(string.Format(I18N.GetString("Port {0} already in use"), pair.Key), e); } else if (se.SocketErrorCode == SocketError.AccessDenied) { e = new Exception(string.Format(I18N.GetString("Port {0} is reserved by system"), pair.Key), se); } } Logging.LogUsefulException(e); ReportError(e); } } Application.Current.Dispatcher?.Invoke(() => { ConfigChanged?.Invoke(this, new EventArgs()); }); UpdateSystemProxy(); Utils.ReleaseMemory(); }
protected void Reload() { // some logic in configuration updated the config when saving, we need to read it again _config = Configuration.Load(); StatisticsConfiguration = StatisticsStrategyConfiguration.Load(); if (polipoRunner == null) { polipoRunner = new PolipoRunner(); } if (_pacServer == null) { _pacServer = new PACServer(); _pacServer.PACFileChanged += pacServer_PACFileChanged; _pacServer.UserRuleFileChanged += pacServer_UserRuleFileChanged; } _pacServer.UpdateConfiguration(_config); if (gfwListUpdater == null) { gfwListUpdater = new GFWListUpdater(); gfwListUpdater.UpdateCompleted += pacServer_PACUpdateCompleted; gfwListUpdater.Error += pacServer_PACUpdateError; } availabilityStatistics.UpdateConfiguration(this); if (_listener != null) { _listener.Stop(); } // don't put polipoRunner.Start() before pacServer.Stop() // or bind will fail when switching bind address from 0.0.0.0 to 127.0.0.1 // though UseShellExecute is set to true now // http://stackoverflow.com/questions/10235093/socket-doesnt-close-after-application-exits-if-a-launched-process-is-open polipoRunner.Stop(); try { var strategy = GetCurrentStrategy(); if (strategy != null) { strategy.ReloadServers(); } polipoRunner.Start(_config); TCPRelay tcpRelay = new TCPRelay(this); UDPRelay udpRelay = new UDPRelay(this); List <Listener.Service> services = new List <Listener.Service>(); services.Add(tcpRelay); services.Add(udpRelay); services.Add(_pacServer); services.Add(new PortForwarder(polipoRunner.RunningPort)); _listener = new Listener(services); _listener.Start(_config); } 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) { SocketException se = (SocketException)e; if (se.SocketErrorCode == SocketError.AccessDenied) { e = new Exception(I18N.GetString("Port already in use"), e); } } Logging.LogUsefulException(e); ReportError(e); } if (ConfigChanged != null) { ConfigChanged(this, new EventArgs()); } UpdateSystemProxy(); Utils.ReleaseMemory(true); }
private void OnAddressFullyRead(IAsyncResult ar) { if (_closed) { return; } try { int bytesRead = _connection.EndReceive(ar); var states = (object[])ar.AsyncState; int bytesRemain = (int)states[0]; var onSuccess = (Action)states[1]; if (bytesRead >= bytesRemain) { _firstPacketLength = bytesRead + 2; int atyp = _connetionRecvBuffer[0]; string dstAddr = "Unknown"; int dstPort = -1; switch (atyp) { case ATYP_IPv4: // IPv4 address, 4 bytes dstAddr = new IPAddress(_connetionRecvBuffer.Skip(1).Take(4).ToArray()).ToString(); dstPort = (_connetionRecvBuffer[5] << 8) + _connetionRecvBuffer[6]; _addrBufLength = ADDR_ATYP_LEN + 4 + ADDR_PORT_LEN; break; case ATYP_DOMAIN: // domain name, length + str int len = _connetionRecvBuffer[1]; dstAddr = System.Text.Encoding.UTF8.GetString(_connetionRecvBuffer, 2, len); dstPort = (_connetionRecvBuffer[len + 2] << 8) + _connetionRecvBuffer[len + 3]; _addrBufLength = ADDR_ATYP_LEN + 1 + len + ADDR_PORT_LEN; break; case ATYP_IPv6: // IPv6 address, 16 bytes dstAddr = $"[{new IPAddress(_connetionRecvBuffer.Skip(1).Take(16).ToArray())}]"; dstPort = (_connetionRecvBuffer[17] << 8) + _connetionRecvBuffer[18]; _addrBufLength = ADDR_ATYP_LEN + 16 + ADDR_PORT_LEN; break; } if (_config.isVerboseLogging) { Logging.Info($"connect to {dstAddr}:{dstPort}"); } _destEndPoint = SocketUtil.GetEndPoint(dstAddr, dstPort); onSuccess.Invoke(); /* StartConnect() */ } else { Logging.Debug("failed to recv data in Shadowsocks.Controller.TCPHandler.OnAddressFullyRead()"); Close(); } } catch (Exception e) { Logging.LogUsefulException(e); Close(); } }
private void StartConnect() { try { CreateRemote(); // Setting up proxy IProxy remote; EndPoint proxyEP = null; EndPoint serverEP = SocketUtil.GetEndPoint(_server.server, _server.server_port); EndPoint pluginEP = _controller.GetPluginLocalEndPointIfConfigured(_server); if (pluginEP != null) { serverEP = pluginEP; remote = new DirectConnect(); } else if (_config.proxy.useProxy) { switch (_config.proxy.proxyType) { case ProxyConfig.PROXY_SOCKS5: remote = new Socks5Proxy(); break; case ProxyConfig.PROXY_HTTP: remote = new HttpProxy(); break; default: throw new NotSupportedException("Unknown forward proxy."); } proxyEP = SocketUtil.GetEndPoint(_config.proxy.proxyServer, _config.proxy.proxyPort); } else { remote = new DirectConnect(); } var session = new AsyncSession(remote); lock (_closeConnLock) { if (_closed) { remote.Close(); return; } _currentRemoteSession = session; } ProxyTimer proxyTimer = new ProxyTimer(_proxyTimeout) { AutoReset = false }; proxyTimer.Elapsed += ProxyConnectTimer_Elapsed; proxyTimer.Enabled = false; proxyTimer.Session = session; proxyTimer.DestEndPoint = serverEP; proxyTimer.Server = _server; _proxyConnected = false; // Connect to the proxy server. remote.BeginConnectProxy(proxyEP, ProxyConnectCallback, new AsyncSession <ProxyTimer>(remote, proxyTimer)); } catch (Exception e) { Logging.LogUsefulException(e); Close(); } }
public static void Update(Configuration config, bool forceDisable) { int sysProxyMode = config.sysProxyMode; if (forceDisable) { sysProxyMode = (int)ProxyMode.Direct; } bool global = sysProxyMode == (int)ProxyMode.Global; bool enabled = sysProxyMode != (int)ProxyMode.Direct; Version win8 = new Version("6.2"); //if (Environment.OSVersion.Version.CompareTo(win8) < 0) { using (RegistryKey registry = OpenUserRegKey(@"Software\Microsoft\Windows\CurrentVersion\Internet Settings", true)) { try { if (enabled) { if (global) { RegistrySetValue(registry, "ProxyEnable", 1); RegistrySetValue(registry, "ProxyServer", "127.0.0.1:" + config.localPort.ToString()); RegistrySetValue(registry, "AutoConfigURL", ""); } else { string pacUrl; pacUrl = "http://127.0.0.1:" + config.localPort.ToString() + "/pac?" + "auth=" + config.localAuthPassword + "&t=" + Util.Utils.GetTimestamp(DateTime.Now); RegistrySetValue(registry, "ProxyEnable", 0); RegistrySetValue(registry, "ProxyServer", ""); RegistrySetValue(registry, "AutoConfigURL", pacUrl); } } else { RegistrySetValue(registry, "ProxyEnable", 0); RegistrySetValue(registry, "ProxyServer", ""); RegistrySetValue(registry, "AutoConfigURL", ""); } IEProxyUpdate(config, sysProxyMode); SystemProxy.NotifyIE(); //Must Notify IE first, or the connections do not chanage CopyProxySettingFromLan(); } catch (Exception e) { Logging.LogUsefulException(e); // TODO this should be moved into views //MessageBox.Show(I18N.GetString("Failed to update registry")); } } } if (Environment.OSVersion.Version.CompareTo(win8) >= 0) { try { if (enabled) { if (global) { WinINet.SetIEProxy(true, true, "127.0.0.1:" + config.localPort.ToString(), ""); } else { string pacUrl; pacUrl = $"http://127.0.0.1:{config.localPort}/pac?auth={config.localAuthPassword}&t={Util.Utils.GetTimestamp(DateTime.Now)}"; WinINet.SetIEProxy(true, false, "", pacUrl); } } else { WinINet.SetIEProxy(false, false, "", ""); } } catch (Exception ex) { Logging.LogUsefulException(ex); } } }
public void Reload() { if (_port_map_listener != null) { foreach (var 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(); Logging.save_to_file = _config.logEnable; Logging.OpenLogFile(); if (_hostDaemon == null) { _hostDaemon = new HostDaemon(); _hostDaemon.ChnIpChanged += (o, args) => ReloadIPRange(); _hostDaemon.UserRuleChanged += (o, args) => HostMap.Reload(); } ReloadIPRange(); HostMap.Reload(); GlobalConfiguration.OSSupportsLocalIPv6 = Socket.OSSupportsIPv6; if (privoxyRunner == null) { privoxyRunner = new HttpProxyRunner(); } if (_pacDaemon == null) { _pacDaemon = new PACDaemon(); _pacDaemon.PACFileChanged += (o, args) => UpdateSystemProxy(); _pacDaemon.UserRuleFileChanged += PacDaemon_UserRuleFileChanged; } if (_pacServer == null) { _pacServer = new PACServer(_pacDaemon); } _pacServer.UpdatePacUrl(_config); if (gfwListUpdater == null) { gfwListUpdater = new GFWListUpdater(); gfwListUpdater.UpdateCompleted += (o, args) => UpdatePACFromGFWListCompleted?.Invoke(o, args); gfwListUpdater.Error += (o, args) => UpdatePACFromGFWListError?.Invoke(o, args); } if (chnDomainsAndIPUpdater == null) { chnDomainsAndIPUpdater = new ChnDomainsAndIPUpdater(); chnDomainsAndIPUpdater.UpdateCompleted += (o, args) => UpdatePACFromChnDomainsAndIPCompleted?.Invoke(o, args); chnDomainsAndIPUpdater.Error += (o, args) => UpdatePACFromGFWListError?.Invoke(o, args); } _listener?.Stop(); privoxyRunner.Stop(); // don't put privoxyRunner.Start() before pacServer.Stop() // or bind will fail when switching bind address from 0.0.0.0 to 127.0.0.1 // though UseShellExecute is set to true now // http://stackoverflow.com/questions/10235093/socket-doesnt-close-after-application-exits-if-a-launched-process-is-open try { privoxyRunner.Start(_config); var local = new Local(_config, _transfer, _chnRangeSet); var services = new List <Listener.IService> { local, _pacServer, new HttpPortForwarder(privoxyRunner.RunningPort, _config) }; _listener = new Listener(services); _listener.Start(_config, 0); } 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) { switch (se.SocketErrorCode) { case SocketError.AddressAlreadyInUse: { e = new Exception(string.Format(I18NUtil.GetAppStringValue(@"PortInUse"), _config.localPort), se); break; } case SocketError.AccessDenied: { e = new Exception(string.Format(I18NUtil.GetAppStringValue(@"PortReserved"), _config.localPort), se); break; } } } Logging.LogUsefulException(e); ReportError(e); } _port_map_listener = new List <Listener>(); foreach (var pair in _config.GetPortMapCache()) { try { var local = new Local(_config, _transfer, _chnRangeSet); var services = new List <Listener.IService> { local }; var 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) { switch (se.SocketErrorCode) { case SocketError.AddressAlreadyInUse: e = new Exception(string.Format(I18NUtil.GetAppStringValue(@"PortInUse"), pair.Key), e); break; case SocketError.AccessDenied: e = new Exception(string.Format(I18NUtil.GetAppStringValue(@"PortReserved"), pair.Key), se); break; } } Logging.LogUsefulException(e); ReportError(e); } } Application.Current.Dispatcher?.Invoke(() => { ConfigChanged?.Invoke(this, new EventArgs()); }); UpdateSystemProxy(); Utils.ReleaseMemory(); }
protected void Reload() { Encryption.RNG.Reload(); // some logic in configuration updated the config when saving, we need to read it again _config = Configuration.Load(); StatisticsConfiguration = StatisticsStrategyConfiguration.Load(); if (_pacServer == null) { _pacServer = new PACServer(); _pacServer.PACFileChanged += pacServer_PACFileChanged; _pacServer.UserRuleFileChanged += pacServer_UserRuleFileChanged; } _pacServer.UpdateConfiguration(_config); if (gfwListUpdater == null) { gfwListUpdater = new GFWListUpdater(); gfwListUpdater.UpdateCompleted += pacServer_PACUpdateCompleted; gfwListUpdater.Error += pacServer_PACUpdateError; } availabilityStatistics.UpdateConfiguration(this); if (_listener != null) { _listener.Stop(); } try { var strategy = GetCurrentStrategy(); if (strategy != null) { strategy.ReloadServers(); } TCPRelay tcpRelay = new TCPRelay(this, _config); UDPRelay udpRelay = new UDPRelay(this); List <Listener.IService> services = new List <Listener.IService>(); services.Add(_pacServer); services.Add(tcpRelay); services.Add(udpRelay); _listener = new Listener(services); _listener.Start(_config); } 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) { SocketException se = (SocketException)e; if (se.SocketErrorCode == SocketError.AccessDenied) { e = new Exception(I18N.GetString("Port already in use"), e); } } Logging.LogUsefulException(e); ReportError(e); } if (ConfigChanged != null) { ConfigChanged(this, new EventArgs()); } UpdateSystemProxy(); Utils.ReleaseMemory(true); }
private void ProxyConnectCallback(IAsyncResult ar) { if (_closed) { return; } try { var session = (AsyncSession <ProxyTimer>)ar.AsyncState; ProxyTimer timer = session.State; var destEndPoint = timer.DestEndPoint; var server = timer.Server; timer.Elapsed -= ProxyConnectTimer_Elapsed; timer.Enabled = false; timer.Dispose(); var remote = session.Remote; // Complete the connection. remote.EndConnectProxy(ar); _proxyConnected = true; if (_config.isVerboseLogging) { if (!(remote is DirectConnect)) { Logging.Info($"Socket connected to proxy {remote.ProxyEndPoint}"); } } _startConnectTime = DateTime.Now; ServerTimer connectTimer = new ServerTimer(_serverTimeout) { AutoReset = false }; connectTimer.Elapsed += DestConnectTimer_Elapsed; connectTimer.Enabled = true; connectTimer.Session = session; connectTimer.Server = server; _destConnected = false; NetworkCredential auth = null; if (_config.proxy.useAuth) { auth = new NetworkCredential(_config.proxy.authUser, _config.proxy.authPwd); } // Connect to the remote endpoint. remote.BeginConnectDest(destEndPoint, ConnectCallback, new AsyncSession <ServerTimer>(session, connectTimer), auth); } catch (ArgumentException) { } catch (Exception e) { Logging.LogUsefulException(e); Close(); } }
private void PipeConnectionReceiveCallback(IAsyncResult ar) { if (_closed) { return; } try { if (connection == null) { return; } int bytesRead = connection.EndReceive(ar); _totalWrite += bytesRead; var session = (AsyncSession <bool>)ar.AsyncState; var remote = session.Remote; if (bytesRead > 0) { /* * Only the first packet contains the socks5 header, it doesn't make sense to parse every packets. * Also it's unnecessary to parse these data if we turn off the VerboseLogging. */ if (session.State && _config.isVerboseLogging) { int atyp = _connetionRecvBuffer[0]; string dst_addr; int dst_port; switch (atyp) { case 1: // IPv4 address, 4 bytes dst_addr = new IPAddress(_connetionRecvBuffer.Skip(1).Take(4).ToArray()).ToString(); dst_port = (_connetionRecvBuffer[5] << 8) + _connetionRecvBuffer[6]; Logging.Info($"connect to {dst_addr}:{dst_port}"); session.State = false; break; case 3: // domain name, length + str int len = _connetionRecvBuffer[1]; dst_addr = System.Text.Encoding.UTF8.GetString(_connetionRecvBuffer, 2, len); dst_port = (_connetionRecvBuffer[len + 2] << 8) + _connetionRecvBuffer[len + 3]; Logging.Info($"connect to {dst_addr}:{dst_port}"); session.State = false; break; case 4: // IPv6 address, 16 bytes dst_addr = new IPAddress(_connetionRecvBuffer.Skip(1).Take(16).ToArray()).ToString(); dst_port = (_connetionRecvBuffer[17] << 8) + _connetionRecvBuffer[18]; Logging.Info($"connect to [{dst_addr}]:{dst_port}"); session.State = false; break; } } int bytesToSend; lock (_encryptionLock) { if (_closed) { return; } encryptor.Encrypt(_connetionRecvBuffer, bytesRead, _connetionSendBuffer, out bytesToSend); } _tcprelay.UpdateOutboundCounter(server, bytesToSend); _startSendingTime = DateTime.Now; _bytesToSend = bytesToSend; remote.BeginSend(_connetionSendBuffer, 0, bytesToSend, SocketFlags.None, new AsyncCallback(PipeRemoteSendCallback), session); IStrategy strategy = controller.GetCurrentStrategy(); strategy?.UpdateLastWrite(server); } else { remote.Shutdown(SocketShutdown.Send); _remoteShutdown = true; CheckClose(); } } catch (Exception e) { Logging.LogUsefulException(e); Close(); } }
private void Connect() { try { IPAddress ipAddress = null; int _targetPort = 0; { if (_firstPacket[0] == 1) { byte[] addr = new byte[4]; Array.Copy(_firstPacket, 1, addr, 0, addr.Length); ipAddress = new IPAddress(addr); _targetPort = (_firstPacket[5] << 8) | _firstPacket[6]; _remote_host = ipAddress.ToString(); Logging.Info((_local_proxy ? "Local proxy" : "Direct") + " connect " + _remote_host + ":" + _targetPort.ToString()); } else if (_firstPacket[0] == 4) { byte[] addr = new byte[16]; Array.Copy(_firstPacket, 1, addr, 0, addr.Length); ipAddress = new IPAddress(addr); _targetPort = (_firstPacket[17] << 8) | _firstPacket[18]; _remote_host = ipAddress.ToString(); Logging.Info((_local_proxy ? "Local proxy" : "Direct") + " connect " + _remote_host + ":" + _targetPort.ToString()); } else if (_firstPacket[0] == 3) { int len = _firstPacket[1]; byte[] addr = new byte[len]; Array.Copy(_firstPacket, 2, addr, 0, addr.Length); _remote_host = Encoding.UTF8.GetString(_firstPacket, 2, len); _targetPort = (_firstPacket[len + 2] << 8) | _firstPacket[len + 3]; Logging.Info((_local_proxy ? "Local proxy" : "Direct") + " connect " + _remote_host + ":" + _targetPort.ToString()); //if (!_local_proxy) { if (!IPAddress.TryParse(_remote_host, out ipAddress)) { if (_config.proxyRuleMode == (int)ProxyRuleMode.UserCustom) { Shadowsocks.Model.HostMap hostMap = HostMap.Instance(); string host_addr; if (hostMap.GetHost(_remote_host, out host_addr)) { if (!String.IsNullOrEmpty(host_addr)) { string lower_host_addr = host_addr.ToLower(); if (lower_host_addr.StartsWith("reject")) { Close(); return; } else if (lower_host_addr.IndexOf('.') >= 0 || lower_host_addr.IndexOf(':') >= 0) { if (!IPAddress.TryParse(lower_host_addr, out ipAddress)) { // } } } } } if (ipAddress == null) { ipAddress = Utils.DnsBuffer.Get(_remote_host); } } if (ipAddress == null) { if (_remote_host.IndexOf('.') >= 0) { ipAddress = Util.Utils.QueryDns(_remote_host, _config.dnsServer); } else { ipAddress = Utils.QueryDns(_remote_host, null); } } if (ipAddress != null) { Utils.DnsBuffer.Set(_remote_host, new IPAddress(ipAddress.GetAddressBytes())); Utils.DnsBuffer.Sweep(); } else { if (!_local_proxy) { throw new SocketException((int)SocketError.HostNotFound); } } } } _remote_port = _targetPort; } if (ipAddress != null && _config.proxyRuleMode == (int)ProxyRuleMode.UserCustom) { Shadowsocks.Model.HostMap hostMap = HostMap.Instance(); string host_addr; if (hostMap.GetIP(ipAddress, out host_addr)) { string lower_host_addr = host_addr.ToLower(); if (lower_host_addr.StartsWith("reject") ) { Close(); return; } } } if (_local_proxy) { IPAddress.TryParse(_config.proxyHost, out ipAddress); _targetPort = _config.proxyPort; } // ProxyAuth recv only socks5 head, so don't need to save anything else IPEndPoint remoteEP = new IPEndPoint(ipAddress, _targetPort); _remote = new ProxySocketTun(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); _remote.GetSocket().NoDelay = true; // Connect to the remote endpoint. _remote.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), null); } catch (Exception e) { Logging.LogUsefulException(e); Close(); } }
public void AcceptCallback(IAsyncResult ar) { if (_stop) { return; } Socket listener = (Socket)ar.AsyncState; try { Socket conn = listener.EndAccept(ar); if ((_authUser ?? "").Length == 0 && !Util.Utils.isLAN(conn)) { conn.Shutdown(SocketShutdown.Both); conn.Close(); } else { byte[] buf = new byte[4096]; object[] state = new object[] { conn, buf }; int local_port = ((IPEndPoint)conn.LocalEndPoint).Port; if (!_config.GetPortMapCache().ContainsKey(local_port)) { conn.BeginReceive(buf, 0, buf.Length, 0, new AsyncCallback(ReceiveCallback), state); } else { foreach (Service service in _services) { if (service.Handle(buf, 0, conn)) { return; } } // no service found for this // shouldn't happen conn.Shutdown(SocketShutdown.Both); conn.Close(); } } } catch (ObjectDisposedException) { } catch (Exception e) { Console.WriteLine(e); } finally { try { listener.BeginAccept( new AsyncCallback(AcceptCallback), listener); } catch (ObjectDisposedException) { // do nothing } catch (Exception e) { Logging.LogUsefulException(e); ResetTimeout(5, listener); } } }
private void Connect() { try { IPAddress ipAddress = null; int _targetPort = 0; { if (_firstPacket[0] == 1) { byte[] addr = new byte[4]; Array.Copy(_firstPacket, 1, addr, 0, addr.Length); ipAddress = new IPAddress(addr); _targetPort = (_firstPacket[5] << 8) | _firstPacket[6]; _remote_host = ipAddress.ToString(); System.Diagnostics.Debug.WriteLine("[" + DateTime.Now.ToString() + "]" + "Direct connect " + _remote_host + ":" + _targetPort.ToString()); } else if (_firstPacket[0] == 4) { byte[] addr = new byte[16]; Array.Copy(_firstPacket, 1, addr, 0, addr.Length); ipAddress = new IPAddress(addr); _targetPort = (_firstPacket[17] << 8) | _firstPacket[18]; _remote_host = ipAddress.ToString(); System.Diagnostics.Debug.WriteLine("[" + DateTime.Now.ToString() + "]" + "Direct connect " + _remote_host + ":" + _targetPort.ToString()); } else if (_firstPacket[0] == 3) { int len = _firstPacket[1]; byte[] addr = new byte[len]; Array.Copy(_firstPacket, 2, addr, 0, addr.Length); _remote_host = Encoding.UTF8.GetString(_firstPacket, 2, len); _targetPort = (_firstPacket[len + 2] << 8) | _firstPacket[len + 3]; System.Diagnostics.Debug.WriteLine("[" + DateTime.Now.ToString() + "]" + "Direct connect " + _remote_host + ":" + _targetPort.ToString()); if (!_remote_go_proxy) { if (!IPAddress.TryParse(_remote_host, out ipAddress)) { ipAddress = Utils.DnsBuffer.Get(_remote_host); } if (ipAddress == null) { ipAddress = Utils.QueryDns(_remote_host, _config.dns_server); } if (ipAddress != null) { Utils.DnsBuffer.Set(_remote_host, ipAddress); Utils.DnsBuffer.Sweep(); } else { throw new SocketException((int)SocketError.HostNotFound); } } } _remote_port = _targetPort; } if (_remote_go_proxy) { IPAddress.TryParse(_config.proxyHost, out ipAddress); _targetPort = _config.proxyPort; } // ProxyAuth recv only socks5 head, so don't need to save anything else IPEndPoint remoteEP = new IPEndPoint(ipAddress, _targetPort); _remote = new ProxySocketTun(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); _remote.GetSocket().SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); // Connect to the remote endpoint. _remote.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), null); } catch (Exception e) { Logging.LogUsefulException(e); Close(); } }
protected void Reload() { Encryption.RNG.Reload(); // some logic in configuration updated the config when saving, we need to read it again _config = Configuration.Load(); StatisticsConfiguration = StatisticsStrategyConfiguration.Load(); privoxyRunner = privoxyRunner ?? new PrivoxyRunner(); _pacDaemon = _pacDaemon ?? new PACDaemon(); _pacDaemon.PACFileChanged += PacDaemon_PACFileChanged; _pacDaemon.UserRuleFileChanged += PacDaemon_UserRuleFileChanged; _pacServer = _pacServer ?? new PACServer(_pacDaemon); gfwListUpdater = gfwListUpdater ?? new GFWListUpdater(); gfwListUpdater.UpdateCompleted += PacServer_PACUpdateCompleted; gfwListUpdater.Error += PacServer_PACUpdateError; availabilityStatistics.UpdateConfiguration(this); _listener?.Stop(); StopPlugins(); // don't put PrivoxyRunner.Start() before pacServer.Stop() // or bind will fail when switching bind address from 0.0.0.0 to 127.0.0.1 // though UseShellExecute is set to true now // http://stackoverflow.com/questions/10235093/socket-doesnt-close-after-application-exits-if-a-launched-process-is-open privoxyRunner.Stop(); try { var strategy = GetCurrentStrategy(); strategy?.ReloadServers(); StartPlugin(); privoxyRunner.Start(_config); TCPRelay tcpRelay = new TCPRelay(this, _config); UDPRelay udpRelay = new UDPRelay(this); List <Listener.IService> services = new List <Listener.IService> { tcpRelay, udpRelay, _pacServer, new PortForwarder(privoxyRunner.RunningPort) }; _listener = new Listener(services); _listener.Start(_config); } 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.AddressAlreadyInUse) { e = new Exception(I18N.GetString("Port {0} already in use", _config.localPort), e); } else if (se.SocketErrorCode == SocketError.AccessDenied) { e = new Exception(I18N.GetString("Port {0} is reserved by system", _config.localPort), e); } } Logging.LogUsefulException(e); ReportError(e); } ConfigChanged?.Invoke(this, new EventArgs()); UpdateSystemProxy(); Utils.ReleaseMemory(true); }
private void AcceptCallback(IAsyncResult ar) { if (_stop) { return; } var listener = (Socket)ar.AsyncState; try { var conn = listener.EndAccept(ar); if (!_shareOverLAN && !Util.Utils.isLocal(conn)) { conn.Shutdown(SocketShutdown.Both); conn.Close(); } var localPort = ((IPEndPoint)conn.LocalEndPoint).Port; if ((_authUser ?? string.Empty).Length == 0 && !Util.Utils.isLAN(conn) && !(_config.GetPortMapCache().ContainsKey(localPort) || _config.GetPortMapCache()[localPort].type == PortMapType.Forward)) { conn.Shutdown(SocketShutdown.Both); conn.Close(); } else { var buf = new byte[4096]; object[] state = { conn, buf }; if (!_config.GetPortMapCache().ContainsKey(localPort) || _config.GetPortMapCache()[localPort].type != PortMapType.Forward) { conn.BeginReceive(buf, 0, buf.Length, 0, ReceiveCallback, state); } else { if (_services.Any(service => service.Handle(buf, 0, conn))) { return; } // no service found for this // shouldn't happen conn.Shutdown(SocketShutdown.Both); conn.Close(); } } } catch (ObjectDisposedException) { } catch (Exception e) { Console.WriteLine(e); } finally { try { listener.BeginAccept(AcceptCallback, listener); } catch (ObjectDisposedException) { // do nothing } catch (Exception e) { Logging.LogUsefulException(e); ResetTimeout(5, listener); } } }
protected void Reload() { 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(); ReloadIPRange(); HostMap hostMap = new HostMap(); hostMap.LoadHostFile(); HostMap.Instance().Clear(hostMap); #if !_CONSOLE if (polipoRunner == null) { polipoRunner = new HttpProxyRunner(); } #endif if (_pacServer == null) { _pacServer = new PACServer(); _pacServer.PACFileChanged += pacServer_PACFileChanged; } _pacServer.UpdateConfiguration(_config); if (gfwListUpdater == null) { gfwListUpdater = new GFWListUpdater(); gfwListUpdater.UpdateCompleted += pacServer_PACUpdateCompleted; gfwListUpdater.Error += pacServer_PACUpdateError; } if (chnDomainsAndIPUpdater == null) { chnDomainsAndIPUpdater = new ChnDomainsAndIPUpdater(); chnDomainsAndIPUpdater.UpdateCompleted += pacServer_PACUpdateCompleted; chnDomainsAndIPUpdater.Error += pacServer_PACUpdateError; } // don't put polipoRunner.Start() before pacServer.Stop() // or bind will fail when switching bind address from 0.0.0.0 to 127.0.0.1 // though UseShellExecute is set to true now // http://stackoverflow.com/questions/10235093/socket-doesnt-close-after-application-exits-if-a-launched-process-is-open 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 !_CONSOLE if (polipoRunner.HasExited()) { polipoRunner.Stop(); polipoRunner.Start(_config); _listener.GetServices()[3] = new HttpPortForwarder(polipoRunner.RunningPort, _config); } #endif } else { if (_listener != null) { _listener.Stop(); _listener = null; } #if !_CONSOLE polipoRunner.Stop(); polipoRunner.Start(_config); #endif Local local = new Local(_config, _transfer, _rangeSet); List <Listener.Service> services = new List <Listener.Service>(); services.Add(local); services.Add(_pacServer); services.Add(new APIServer(this, _config)); #if !_CONSOLE services.Add(new HttpPortForwarder(polipoRunner.RunningPort, _config)); #endif _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) { SocketException se = (SocketException)e; 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.Service> services = new List <Listener.Service>(); 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) { SocketException se = (SocketException)e; 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()); UpdateSystemProxy(); Util.Utils.ReleaseMemory(); }
public void Start(Configuration config, int port) { _config = config; _shareOverLAN = config.shareOverLan; _authUser = config.authUser; _authPass = config.authPass; _stop = false; var localPort = port == 0 ? _config.localPort : port; if (CheckIfPortInUse(localPort)) { throw new Exception(I18N.GetString("Port already in use")); } try { // Create a TCP/IP socket. _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); try { _socket_v6 = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp); _socket_v6.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); } catch { _socket_v6 = null; } var localEndPoint = new IPEndPoint(IPAddress.Any, localPort); var localEndPointV6 = new IPEndPoint(IPAddress.IPv6Any, localPort); // Bind the socket to the local endpoint and listen for incoming connections. _socket.Bind(localEndPoint); _socket.Listen(1024); if (_socket_v6 != null) { _socket_v6.Bind(localEndPointV6); _socket_v6.Listen(1024); } // Start an asynchronous socket to listen for connections. Console.WriteLine($@"ShadowsocksR started on port {localPort}"); _socket.BeginAccept(AcceptCallback, _socket); _socket_v6?.BeginAccept(AcceptCallback, _socket_v6); } catch (SocketException e) { Logging.LogUsefulException(e); if (_socket != null) { _socket.Close(); _socket = null; } if (_socket_v6 != null) { _socket_v6.Close(); _socket_v6 = null; } throw; } }
public void Start(int port = 0) { _stop = false; int localPort = port == 0 ? Config.localPort : port; if (CheckIfPortInUse(localPort)) { throw new Exception(I18N.GetString("Port already in use")); } try { // Create a TCP/IP socket. bool ipv6 = true; //bool ipv6 = false; _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); if (ipv6) { try { _socket_v6 = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp); //_socket_v6.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)27, false); _socket_v6.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); } catch { _socket_v6 = null; } } IPEndPoint localEndPoint = null; IPEndPoint localEndPointV6 = null; localEndPoint = new IPEndPoint(IPAddress.Any, localPort); localEndPointV6 = new IPEndPoint(IPAddress.IPv6Any, localPort); // Bind the socket to the local endpoint and listen for incoming connections. if (_socket_v6 != null) { _socket_v6.Bind(localEndPointV6); _socket_v6.Listen(1024); } //try { //throw new SocketException(); _socket.Bind(localEndPoint); _socket.Listen(1024); } //catch (SocketException e) //{ // if (_socket_v6 == null) // { // throw e; // } // else // { // _socket.Close(); // _socket = _socket_v6; // _socket_v6 = null; // } //} // Start an asynchronous socket to listen for connections. Console.WriteLine("ShadowsocksR started on port " + localPort.ToString()); _socket.BeginAccept( new AsyncCallback(AcceptCallback), _socket); if (_socket_v6 != null) { _socket_v6.BeginAccept( new AsyncCallback(AcceptCallback), _socket_v6); } } catch (SocketException e) { Logging.LogUsefulException(e); if (_socket != null) { _socket.Close(); _socket = null; } if (_socket_v6 != null) { _socket_v6.Close(); _socket_v6 = null; } throw; } }