LogUsefulException() 공개 정적인 메소드

public static LogUsefulException ( Exception e ) : void
e System.Exception
리턴 void
예제 #1
0
        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();
        }
예제 #2
0
        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);
        }
예제 #3
0
        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();
            }
        }
예제 #4
0
        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();
            }
        }
예제 #5
0
        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);
                }
            }
        }
예제 #6
0
        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();
        }
예제 #7
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);
        }
예제 #8
0
        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();
            }
        }
예제 #9
0
        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();
            }
        }
예제 #10
0
            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();
                }
            }
예제 #11
0
        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);
                }
            }
        }
예제 #12
0
            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);
        }
예제 #14
0
파일: Listener.cs 프로젝트: RAJAKONA/SSRW
        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);
                }
            }
        }
예제 #15
0
        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();
        }
예제 #16
0
파일: Listener.cs 프로젝트: RAJAKONA/SSRW
        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;
            }
        }
예제 #17
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;
            }
        }