示例#1
0
 public static void CheckPort(int port)
 {
     if (port <= IPEndPoint.MinPort || port > IPEndPoint.MaxPort)
     {
         throw new ConfigurationException(I18NUtil.GetAppStringValue(@"PortOutOfRange"));
     }
 }
示例#2
0
        private void LoadLanguage()
        {
            UpdateTitle();

            foreach (var c in ViewUtils.FindVisualChildren <Label>(this))
            {
                c.Content = I18N.GetString(c.Content.ToString());
            }

            foreach (var c in ViewUtils.FindVisualChildren <Button>(this))
            {
                c.Content = I18N.GetString(c.Content.ToString());
            }

            foreach (var c in ViewUtils.FindVisualChildren <CheckBox>(this))
            {
                c.Content = I18N.GetString(c.Content.ToString());
            }

            foreach (var c in ViewUtils.FindVisualChildren <GroupBox>(this))
            {
                c.Header = I18N.GetString(c.Header.ToString());
            }

            ProxyTypeComboBox.Items.Add(I18N.GetString(@"Socks5(support UDP)"));
            ProxyTypeComboBox.Items.Add(I18N.GetString(@"Http tunnel"));
            ProxyTypeComboBox.Items.Add(I18N.GetString(@"TCP Port tunnel"));
            foreach (var value in Enum.GetValues(typeof(LoadBalance)))
            {
                var str = value.ToString();
                _balanceIndexMap.Add(str);
                BalanceComboBox.Items.Add(I18NUtil.GetAppStringValue(str));
            }
        }
        private static void ThrowSocketException(ref Exception e)
        {
            // TODO: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
            // https://docs.microsoft.com/zh-cn/dotnet/api/system.net.sockets.socketerror
            if (e is not SocketException se)
            {
                return;
            }

            switch (se.SocketErrorCode)
            {
            case SocketError.AddressAlreadyInUse:
            {
                e = new Exception(string.Format(I18NUtil.GetAppStringValue(@"PortInUse"), Global.GuiConfig.LocalPort), se);
                break;
            }

            case SocketError.AccessDenied:
            {
                e = new Exception(string.Format(I18NUtil.GetAppStringValue(@"PortReserved"), Global.GuiConfig.LocalPort), se);
                break;
            }
            }
        }
示例#4
0
 public static void CheckPort(int port)
 {
     if (!IsPort(port))
     {
         throw new ConfigurationException(I18NUtil.GetAppStringValue(@"PortOutOfRange"));
     }
 }
示例#5
0
 public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
 {
     if (value is ProxyType type)
     {
         return(I18NUtil.GetAppStringValue(type.ToString()));
     }
     return(DependencyProperty.UnsetValue);
 }
示例#6
0
 private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
 {
     if (Interlocked.Increment(ref _exited) == 1)
     {
         Logging.Log(LogLevel.Error, $@"{e.ExceptionObject}");
         MessageBox.Show(
             $@"{I18NUtil.GetAppStringValue(@"UnexpectedError")}{Environment.NewLine}{e.ExceptionObject}",
             UpdateChecker.Name, MessageBoxButton.OK, MessageBoxImage.Error);
         Application.Current.Shutdown();
     }
 }
示例#7
0
 private void LoadItems()
 {
     ProxyTypeComboBox.Items.Add(this.GetWindowStringValue(@"Socks5"));
     ProxyTypeComboBox.Items.Add(this.GetWindowStringValue(@"Http"));
     ProxyTypeComboBox.Items.Add(this.GetWindowStringValue(@"TcpPortTunnel"));
     foreach (var value in Enum.GetValues(typeof(LoadBalance)))
     {
         var str = value.ToString();
         _balanceIndexMap.Add(str);
         BalanceComboBox.Items.Add(I18NUtil.GetAppStringValue(str));
     }
 }
示例#8
0
 private static void SingleInstance_ArgumentsReceived(object sender, ArgumentsReceivedEventArgs e)
 {
     if (e.Args.Contains(Constants.ParameterMultiplyInstance))
     {
         MessageBox.Show(I18NUtil.GetAppStringValue(@"SuccessiveInstancesMessage1") + Environment.NewLine +
                         I18NUtil.GetAppStringValue(@"SuccessiveInstancesMessage2"),
                         I18NUtil.GetAppStringValue(@"SuccessiveInstancesCaption"), MessageBoxButton.OK, MessageBoxImage.Information);
     }
     Application.Current.Dispatcher?.Invoke(() =>
     {
         _viewController.ImportAddress(string.Join(Environment.NewLine, e.Args));
     });
 }
示例#9
0
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value is bool enable)
            {
                if (targetType == typeof(string))
                {
                    return(I18NUtil.GetAppStringValue(enable ? @"Enabled" : @"Disabled"));
                }

                if (targetType == typeof(Brush))
                {
                    return(enable ? Brushes.Green : Brushes.Red);
                }
            }
            return(DependencyProperty.UnsetValue);
        }
        private void ThrowSocketException(ref 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;
                }
                }
            }
        }
示例#11
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);

            GlobalConfiguration.OSSupportsLocalIPv6 = Socket.OSSupportsIPv6;

            if (privoxyRunner == null)
            {
                privoxyRunner = new HttpProxyRunner();
            }
            if (_pacDaemon == null)
            {
                _pacDaemon = new PACDaemon();
                _pacDaemon.PACFileChanged      += PacDaemon_PACFileChanged;
                _pacDaemon.UserRuleFileChanged += PacDaemon_UserRuleFileChanged;
            }
            if (_pacServer == null)
            {
                _pacServer = new PACServer(_pacDaemon);
            }
            _pacServer.UpdatePacUrl(_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();

            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, _rangeSet);
                var services = new List <Listener.IService>
                {
                    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)
                {
                    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, _rangeSet);
                    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)
                    {
                        if (se.SocketErrorCode == SocketError.AddressAlreadyInUse)
                        {
                            e = new Exception(string.Format(I18NUtil.GetAppStringValue(@"PortInUse"), pair.Key), e);
                        }
                        else if (se.SocketErrorCode == SocketError.AccessDenied)
                        {
                            e = new Exception(string.Format(I18NUtil.GetAppStringValue(@"PortReserved"), pair.Key), se);
                        }
                    }
                    Logging.LogUsefulException(e);
                    ReportError(e);
                }
            }

            Application.Current.Dispatcher?.Invoke(() => { ConfigChanged?.Invoke(this, new EventArgs()); });

            UpdateSystemProxy();
            Utils.ReleaseMemory();
        }
        public void Start(Configuration config, int port)
        {
            _config       = config;
            _shareOverLan = config.ShareOverLan;
            _authUser     = config.AuthUser;

            var localPort = port == 0 ? _config.LocalPort : port;

            if (CheckIfPortInUse(localPort))
            {
                throw new Exception(string.Format(I18NUtil.GetAppStringValue(@"PortInUse"), localPort));
            }

            try
            {
                //TODO:UDP socket
                // Create a TCP/IP socket.
                _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                var localEndPoint = new IPEndPoint(_shareOverLan ? IPAddress.Any : IPAddress.Loopback, localPort);
                // Bind the socket to the local endpoint and listen for incoming connections.
                _socket.Bind(localEndPoint);
                _socket.Listen(1024);

                // IPv6
                if (Global.OSSupportsLocalIPv6)
                {
                    try
                    {
                        _socketV6 = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
                        _socketV6.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                    }
                    catch
                    {
                        _socketV6 = null;
                    }
                    var localEndPointV6 = new IPEndPoint(_shareOverLan ? IPAddress.IPv6Any : IPAddress.IPv6Loopback, localPort);
                    if (_socketV6 != null)
                    {
                        _socketV6.Bind(localEndPointV6);
                        _socketV6.Listen(1024);
                    }
                }
                else
                {
                    _socketV6 = null;
                }

                // Start an asynchronous socket to listen for connections.
                Console.WriteLine($@"ShadowsocksR started on port {localPort}");
                _socket.BeginAccept(AcceptCallback, _socket);
                _socketV6?.BeginAccept(AcceptCallback, _socketV6);
            }
            catch (SocketException e)
            {
                Logging.LogUsefulException(e);
                if (_socket != null)
                {
                    _socket.Close();
                    _socket = null;
                }
                if (_socketV6 != null)
                {
                    _socketV6.Close();
                    _socketV6 = null;
                }
                throw;
            }
        }
示例#13
0
        private static void Main(string[] args)
        {
            Directory.SetCurrentDirectory(Path.GetDirectoryName(Utils.GetExecutablePath()) ?? throw new InvalidOperationException());
            var identifier = $@"Global\{Controller.HttpRequest.UpdateChecker.Name}_{Directory.GetCurrentDirectory().GetClassicHashCode()}";

            using var singleInstance = new SingleInstanceService(identifier);
            if (!singleInstance.IsFirstInstance)
            {
                singleInstance.PassArgumentsToFirstInstance(args.Length == 0
                        ? args.Append(Constants.ParameterMultiplyInstance)
                        : args);
                return;
            }
            singleInstance.ArgumentsReceived.Subscribe(SingleInstance_ArgumentsReceived);

            var app = new Application
            {
                ShutdownMode = ShutdownMode.OnExplicitShutdown
            };

            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

            SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
            app.Exit += App_Exit;

            Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense(@"##SyncfusionLicense##");

            Global.LoadConfig();

            I18NUtil.SetLanguage(Global.GuiConfig.LangName);
            ViewUtils.SetResource(app.Resources, @"../View/NotifyIconResources.xaml", 1);

            Global.Controller = new MainController();

            // Logging
            Logging.DefaultOut   = Console.Out;
            Logging.DefaultError = Console.Error;

            Utils.SetTls();

            Global.ViewController       = new MenuViewController(Global.Controller);
            SystemEvents.SessionEnding += Global.ViewController.Quit_Click;

            Global.Controller.Reload();
            if (Global.GuiConfig.IsDefaultConfig())
            {
                var res = MessageBox.Show(
                    $@"{I18NUtil.GetAppStringValue(@"DefaultConfigMessage")}{Environment.NewLine}{I18NUtil.GetAppStringValue(@"DefaultConfigQuestion")}",
                    Controller.HttpRequest.UpdateChecker.Name, MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.OK);
                switch (res)
                {
                case MessageBoxResult.Yes:
                {
                    Global.Controller.ShowConfigForm();
                    break;
                }

                case MessageBoxResult.No:
                {
                    Global.Controller.ShowSubscribeWindow();
                    break;
                }

                default:
                {
                    StopController();
                    return;
                }
                }
            }

            Reg.SetUrlProtocol(@"ssr");
            Reg.SetUrlProtocol(@"sub");

            singleInstance.ListenForArgumentsFromSuccessiveInstances();
            app.Run();
        }
示例#14
0
        private void ServersTreeView_OnDragEnd(object sender, DragTreeViewItemAdvEventArgs e)
        {
            //Fix weird selections
            ServersTreeView.ClearSelection();

            var draggingItems = new List <ServerTreeViewModel>();

            foreach (var draggingItem in e.DraggingItems)
            {
                if (draggingItem.Header is ServerTreeViewModel st)
                {
                    draggingItems.Add(st);
                }
                else
                {
                    goto Skip;
                }
            }
            var types = new HashSet <ServerTreeViewType>(draggingItems.Select(items => items.Type));

            if (types.Count == 1)
            {
                var type = types.First();
                switch (type)
                {
                case ServerTreeViewType.Subtag:
                    e.Cancel = !(e.TargetDropItem is TreeViewAdv);
                    return;

                case ServerTreeViewType.Group:
                    //移到相同订阅组上会被吃掉
                    if (e.DropIndex < 0)
                    {
                        goto Skip;
                    }
                    //属于同样的订阅
                    if (e.TargetDropItem is TreeViewItemAdv treeViewItem)
                    {
                        if (treeViewItem.Header is ServerTreeViewModel st && st.Type == ServerTreeViewType.Subtag)
                        {
                            if (draggingItems.All(draggingItem => draggingItem.Parent == st))
                            {
                                e.Cancel = false;
                                return;
                            }
                        }
                    }
                    break;

                case ServerTreeViewType.Server:
                    //属于同一个订阅
                    var subs = new HashSet <string>();
                    foreach (var draggingItem in draggingItems)
                    {
                        var parent = draggingItem.Parent;
                        while (parent.Parent != null)
                        {
                            parent = parent.Parent;
                        }
                        if (parent is ServerTreeViewModel parentModel)
                        {
                            subs.Add(parentModel.Name);
                            continue;
                        }
                        goto Skip;
                    }
                    if (subs.Count != 1)
                    {
                        goto Skip;
                    }
                    var sub = subs.First();
                    //且 目标为群组或原版的订阅连接
                    if (e.TargetDropItem is TreeViewItemAdv treeViewItemAdv)
                    {
                        if (treeViewItemAdv.Header is ServerTreeViewModel st)
                        {
                            switch (st.Type)
                            {
                            case ServerTreeViewType.Subtag:
                            {
                                //移到相同订阅组上会被吃掉
                                if (e.DropIndex < 0)
                                {
                                    goto Skip;
                                }
                                //原版的订阅连接
                                if (draggingItems.All(draggingItem => draggingItem.Parent == st))
                                {
                                    e.Cancel = false;
                                    return;
                                }
                                break;
                            }

                            case ServerTreeViewType.Group:
                            {
                                //相同订阅组
                                if (st.Parent is ServerTreeViewModel targetParent && sub == targetParent.Name)
                                {
                                    //同一个组
                                    var parents = new HashSet <IVirtualTree>(draggingItems.Select(items => items.Parent));
                                    if (parents.Count != 1)
                                    {
                                        goto Skip;
                                    }
                                    var parent = parents.First();
                                    if (e.DropIndex < 0 && parent == st)
                                    {
                                        goto Skip;
                                    }

                                    foreach (var draggingItem in draggingItems)
                                    {
                                        var first = st.Nodes.FirstOrDefault();
                                        draggingItem.Server.Group = first != null ? first.Server.Group :
                                                                    st.Name != I18NUtil.GetAppStringValue(@"EmptyGroup") ? st.Name :
                                                                    string.Empty;
                                        draggingItem.Parent = st;
                                    }
                                    e.Cancel = false;
                                    return;
                                }
                                break;
                            }
                            }
                        }
                    }
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
Skip:
            e.Cancel = true;
        }
示例#15
0
 public ImageWindow()
 {
     InitializeComponent();
     Title   = I18NUtil.GetAppStringValue(@"Donate");
     Height += SystemParameters.WindowCaptionHeight;
 }
示例#16
0
        private static void Main(string[] args)
        {
            Directory.SetCurrentDirectory(Path.GetDirectoryName(Utils.GetExecutablePath()) ?? throw new InvalidOperationException());
            if (args.Contains(Constants.ParameterSetautorun))
            {
                if (!AutoStartup.Switch())
                {
                    Environment.ExitCode = 1;
                }
                return;
            }

            var identifier = $@"Global\{UpdateChecker.Name}_{Directory.GetCurrentDirectory().GetDeterministicHashCode()}";

            using var singleInstance = new SingleInstance(identifier);
            if (!singleInstance.IsFirstInstance)
            {
                singleInstance.PassArgumentsToFirstInstance(args.Length == 0
                        ? args.Append(Constants.ParameterMultiplyInstance)
                        : args);
                return;
            }
            singleInstance.ArgumentsReceived += SingleInstance_ArgumentsReceived;

            var app = new Application
            {
                ShutdownMode = ShutdownMode.OnExplicitShutdown
            };

            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

            SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
            app.Exit += App_Exit;

            Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense(@"##SyncfusionLicense##");

            I18NUtil.SetLanguage(Configuration.Load().LangName);
            ViewUtils.SetResource(app.Resources, @"../View/NotifyIconResources.xaml", 1);

            _controller = new ShadowsocksController();
            HostMap.Instance().LoadHostFile();

            // Logging
            Logging.DefaultOut   = Console.Out;
            Logging.DefaultError = Console.Error;

            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls13 | SecurityProtocolType.Tls12;

            _viewController             = new MenuViewController(_controller);
            SystemEvents.SessionEnding += _viewController.Quit_Click;

            _controller.Start();
            if (_controller.IsDefaultConfig())
            {
                var res = MessageBox.Show(
                    $@"{I18NUtil.GetAppStringValue(@"DefaultConfigMessage")}{Environment.NewLine}{I18NUtil.GetAppStringValue(@"DefaultConfigQuestion")}",
                    UpdateChecker.Name, MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.OK);
                switch (res)
                {
                case MessageBoxResult.Yes:
                {
                    _controller.ShowConfigForm();
                    break;
                }

                case MessageBoxResult.No:
                {
                    _controller.ShowSubscribeWindow();
                    break;
                }

                default:
                {
                    StopController();
                    return;
                }
                }
            }
#if !DEBUG
            Reg.SetUrlProtocol(@"ssr");
            Reg.SetUrlProtocol(@"sub");
#endif
            singleInstance.ListenForArgumentsFromSuccessiveInstances();
            app.Run();
        }