public void Start(Configuration config) { this._config = config; if (CheckIfPortInUse(_config.localPort)) { throw new SSPortAlreadyInUseException(); } this._shareOverLAN = config.shareOverLan; var tcpservice = new TCPRelay(_config); tcpservice.OnClose += this.Broken; var udpservice = new UDPRelay(_config); udpservice.OnClose += this.Broken; AddService(tcpservice); AddService(udpservice); try { // Create a TCP/IP socket. _tcpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _udpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); _tcpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); _udpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); IPEndPoint localEndPoint = null; if (_shareOverLAN) { localEndPoint = new IPEndPoint(IPAddress.Any, _config.localPort); } else { localEndPoint = new IPEndPoint(IPAddress.Loopback, _config.localPort); } // Bind the socket to the local endpoint and listen for incoming connections. _tcpSocket.Bind(localEndPoint); _udpSocket.Bind(localEndPoint); _tcpSocket.Listen(1024); // Start an asynchronous socket to listen for connections. Trace.WriteLine("Shadowsocks started"); _tcpSocket.BeginAccept( new AsyncCallback(AcceptCallback), _tcpSocket); UDPState udpState = new UDPState(); _udpSocket.BeginReceiveFrom(udpState.buffer, 0, udpState.buffer.Length, 0, ref udpState.remoteEndPoint, new AsyncCallback(RecvFromCallback), udpState); } catch (SocketException) { _tcpSocket.Close(); this.Broken(); throw; } }
public void Start(string listenSocks, string serverAddress, int serverPort, string method, string password, string?plugin, string?pluginOpts, string?pluginArgs) { var localEP = IPEndPoint.Parse(listenSocks); var server = new Server() { Host = serverAddress, Port = serverPort, Method = method, Password = password, Plugin = plugin, PluginOpts = pluginOpts, }; if (!string.IsNullOrEmpty(plugin) && !string.IsNullOrEmpty(pluginArgs)) { var processStartInfo = new ProcessStartInfo(plugin, pluginArgs); server.PluginArgs = processStartInfo.ArgumentList.ToList(); } var tcpRelay = new TCPRelay(server); _tcpListener = new TCPListener(localEP, new List <IStreamService>() { tcpRelay, }); _tcpListener.Start(); var udpRelay = new UDPRelay(server); _udpListener = new UDPListener(localEP, new List <IDatagramService>() { udpRelay, }); _udpListener.Start(); }
protected void Reload() { // some logic in configuration updated the config when saving, we need to read it again _config = Configuration.Load(); if (polipoRunner == null) { polipoRunner = new PolipoRunner(); } 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 (_listener != null) { _listener.Stop(); } if (_availabilityStatics == null) { _availabilityStatics = new AvailabilityStatistics(); _availabilityStatics.UpdateConfiguration(_config); } // 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(); Util.Utils.ReleaseMemory(true); }
public void Start(Configuration config) { this._config = config; if (CheckIfPortInUse(_config.localPort)) throw new SSPortAlreadyInUseException(); this._shareOverLAN = config.shareOverLan; var tcpservice = new TCPRelay(_config); tcpservice.OnClose += this.Broken; var udpservice = new UDPRelay(_config); udpservice.OnClose += this.Broken; AddService(tcpservice); AddService(udpservice); try { // Create a TCP/IP socket. _tcpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _udpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); _tcpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); _udpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); IPEndPoint localEndPoint = null; if (_shareOverLAN) { localEndPoint = new IPEndPoint(IPAddress.Any, _config.localPort); } else { localEndPoint = new IPEndPoint(IPAddress.Loopback, _config.localPort); } // Bind the socket to the local endpoint and listen for incoming connections. _tcpSocket.Bind(localEndPoint); _udpSocket.Bind(localEndPoint); _tcpSocket.Listen(1024); // Start an asynchronous socket to listen for connections. Trace.WriteLine("Shadowsocks started"); _tcpSocket.BeginAccept( new AsyncCallback(AcceptCallback), _tcpSocket); UDPState udpState = new UDPState(); _udpSocket.BeginReceiveFrom(udpState.buffer, 0, udpState.buffer.Length, 0, ref udpState.remoteEndPoint, new AsyncCallback(RecvFromCallback), udpState); } catch (SocketException) { _tcpSocket.Close(); this.Broken(); throw; } }
protected void Reload() { // some logic in configuration updated the config when saving, we need to read it again _config = Configuration.Load(); if (_listener != null) { _listener.Stop(); } if (_availabilityStatics == null) { _availabilityStatics = new AvailabilityStatistics(); _availabilityStatics.UpdateConfiguration(_config); } try { var strategy = GetCurrentStrategy(); if (strategy != null) { strategy.ReloadServers(); } TCPRelay tcpRelay = new TCPRelay(this); UDPRelay udpRelay = new UDPRelay(this); List<Listener.Service> services = new List<Listener.Service>(); 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()); } Util.Utils.ReleaseMemory(true); }
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.UpdateConfiguration(_config); if (gfwListUpdater == null) { gfwListUpdater = new GFWListUpdater(); gfwListUpdater.UpdateCompleted += pacServer_PACUpdateCompleted; gfwListUpdater.Error += pacServer_PACUpdateError; } if (availabilityStatistics == null) { availabilityStatistics = new AvailabilityStatistics(_config, StatisticsConfiguration); } availabilityStatistics.UpdateConfiguration(_config, StatisticsConfiguration); 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); // 开启本地socks5 tcp代理服务 services.Add(udpRelay); // 开启本地socks5 udp代理服务 services.Add(_pacServer); // 开启本地pac服务器 /* 这里是shadowsocks-windows能成为http代理的关键之处。:100: 我们在对ss-windows设置各种代理模式时,实际上只是对系统的internet选项进行的http代理设置。 我们知道,ss服务器是一个socks协议的代理,为什么对系统的http代理请求也能起作用呢? 当ss-windows启动时,同时会启动privoxy.exe(监听8123端口,可配置),privoxy是一个http代理,它收到http请求后, 转化成socks协议的数据,再转发给ss端口,由ss访问internet,再层层向回发。 http请求 转发给 封包成socks5协议,转发给 browser-------------> ss socks5 代理 ----------------------> privoxy -----------------------------> ss socks5 代理 <-------------- <---------------------- <----------------------------- 转发http响应数据 封包成http形式数据 将结果以socks5形式返回 */ services.Add(new PortForwarder(polipoRunner.RunningPort)); //开启本地http代理服务 _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(); Util.Utils.ReleaseMemory(true); }