SS-windows源码分析[1]-代理服务器配置是如何管理的

楚天乐 5387 0 条

介绍

本系列文章介绍请看:概述

本文旨在搞清楚以下问题:

  • 代理服务器数据结构

数据结构

  • 代理服务器管理界面
    WeChat Image_20180923181038.png

  • 代理服务器数据结构
    代码位置Model/Server.cs

namespace Shadowsocks.Model
{
    [Serializable]
    public class Server
    {
        #region ParseLegacyURL
        public static readonly Regex
            UrlFinder = new Regex(@"ss://(?<base64>[A-Za-z0-9+-/=_]+)(?:#(?<tag>\S+))?", RegexOptions.IgnoreCase),
            DetailsParser = new Regex(@"^((?<method>.+?):(?<password>.*)@(?<hostname>.+?):(?<port>\d+?))$", RegexOptions.IgnoreCase);
        #endregion ParseLegacyURL

        private const int DefaultServerTimeoutSec = 5;
        public const int MaxServerTimeoutSec = 20;

        public string server;       // 代理服务器名字
        public int server_port;     // 服务器端口
        public string password;     // 服务器密码
        public string method;       // 加密方式
        public string plugin;       // 插件程序
        public string plugin_opts;  // 插件选项
        public string plugin_args;  // 插件参数
        public string remarks;      // 备注
        public int timeout;         // 超时时间

        // 计算hash
        public override int GetHashCode(){.........}

        // 判断俩Server一样
        public override bool Equals(object obj){.........}

        // 生成当前server对象的友好名字,格式:  IP:PORT:REMARKS
        public string FriendlyName(){.........}

        // 格式化host name
        public string FormatHostName(string hostName){.........}

        // 构造函数
        public Server(){.........}

        // 从SSURL中解析Server对象,这里不去关注ssurl结构和解析方法
        private static Server ParseLegacyURL(string ssURL){.........}

        // 从SSURL中解析Server对象列表,这里不去关注ssurl结构和解析方法
        public static List<Server> GetServers(string ssURL){.........}

        // 获得当前服务器对象的标识:IP:PORT
        public string Identifier(){.........}
    }
}

可以看到,这里的数据结构和上面操作界面图中是一致的。

代理服务器配置管理

有了代理服务器数据结构,就可以进一步看该项目如何管理代理服务器配置了。

  • 获得代理服务器列表
    call stack:
    View/CinfigForm.cs :
    ConfigForm::ConfigForm -> ConfigForm::LoadCurrentConfiguration
    Controller/ShadowsocksController.cs :
    -> controller.GetConfigurationCopy
    Model/Configuration.cs :
    -> Configuration.Load

这里我们就来看看Configuration.Load是如何实现的

public static Configuration Load()
{
    try
    {
        string configContent = File.ReadAllText(CONFIG_FILE);
        Configuration config = JsonConvert.DeserializeObject<Configuration>(configContent);
        config.isDefault = false;

        if (config.configs == null)
            config.configs = new List<Server>();
        if (config.configs.Count == 0)
            config.configs.Add(GetDefaultServer());
        if (config.localPort == 0)
            config.localPort = 1080;
        if (config.index == -1 && config.strategy == null)
            config.index = 0;
        if (config.logViewer == null)
            config.logViewer = new LogViewerConfig();
        if (config.proxy == null)
            config.proxy = new ProxyConfig();
        if (config.hotkey == null)
            config.hotkey = new HotkeyConfig();

        config.proxy.CheckConfig();

        return config;
    }
    catch (Exception e)
    {
        if (!(e is FileNotFoundException))
            Logging.LogUsefulException(e);
        return new Configuration
        {
            index = 0,
            isDefault = true,
            localPort = 1080,
            autoCheckUpdate = true,
            configs = new List<Server>()
            {
                GetDefaultServer()
            },
            logViewer = new LogViewerConfig(),
            proxy = new ProxyConfig(),
            hotkey = new HotkeyConfig()
        };
    }
}

代码非常简单,我就不一行一行解释了。客户端的配置使用json格式保存,直接json decode即可。容错处理此处不多说。
返回的config对象中:

config.configs:服务器列表,List
config.localPort:本机端口
config.index:当前服务器索引号
config.logViewer:当前日志配置
config.proxy:当前代理设置
config.hotkey:当前热键设置

这段代码紧接下来就是配置文件保存方法

public static void Save(Configuration config)
{
    if (config.index >= config.configs.Count)
        config.index = config.configs.Count - 1;
    if (config.index < -1)
        config.index = -1;
    if (config.index == -1 && config.strategy == null)
        config.index = 0;
    config.isDefault = false;
    try
    {
        using (StreamWriter sw = new StreamWriter(File.Open(CONFIG_FILE, FileMode.Create)))
        {
            string jsonString = JsonConvert.SerializeObject(config, Formatting.Indented);
            sw.Write(jsonString);
            sw.Flush();
        }
    }
    catch (IOException e)
    {
        Logging.LogUsefulException(e);
    }
}

看到这里就清楚了,全系统的配置都保存在一个Configuration config对象中,由Model/Configuration类管理。

打赏

微信打赏

支付宝打赏



与本文相关的文章

发表我的评论
昵称 (必填)
邮箱 (必填)
网址
执行时间: 79.725980758667 毫秒