예제 #1
0
        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);
        }
예제 #2
0
        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;
            }
        }