// 更新配置 // hosts 本地文件会直接载入 // 不存在时打印警告,但是不出错退出,等新建 hosts 文件时将会自动载入 // hosts http、https 文件,定时更新。 // 每次配置重新载入所有的配置文件,并不是函数返回配置就立刻生效,配置生效需要时间。 func (h *hostsDns) Config(c *DnschanHostsConfig) error { newUFile, err := ufile.NewUFile(c.BashPath, hostsCheckInterval) if err != nil { return err } for _, hosts := range c.Hostss { if strings.TrimSpace(hosts.Type) == "" { hosts.Type = "base" } } for _, hosts := range c.Hostss { // 解析更新间隔 if lpath := strings.ToLower(hosts.Path); hosts.UpdateInterval == "" && strings.HasPrefix(lpath, "http://") == false && strings.HasPrefix(lpath, "https://") == false { // 本地文件不存在更新间隔时自动补一个,其实没有用处。 hosts.UpdateInterval = "1h" } updateInterval, err := time.ParseDuration(hosts.UpdateInterval) if err != nil { newUFile.Close() return fmt.Errorf("hosts 配置错误:updateInterval (%v) 格式不是正确的时间格式:%v", hosts.UpdateInterval, err) } // 类型 domainType, err := domains.ParseDomainType(hosts.Type) if err != nil { return fmt.Errorf("未知的 hosts 类型:%v", hosts.Type) } // userdata name := fmt.Sprint(domainType, "-", hosts.Credit, "-", hosts.Path) userdata := ufileUserdata{ name: name, domainType: domainType, credit: hosts.Credit, } if err := newUFile.Add(hosts.Path, updateInterval, &userdata); err != nil { newUFile.Close() return err } } // 配置没有明显错误,使用新配置 h.rwm.Lock() defer h.rwm.Unlock() if h.uf != nil { h.uf.Close() //关闭老配置的自动更新 } newDomains := domains.NewDomains(hostsCacheSize) h.ds = newDomains h.uf = newUFile go h.loop(newUFile, newDomains) return nil }
func (d *DialClients) Config(config *ConfigDialClients) (rerr error) { newClients := make([]*DialClient, 0, len(config.UpStreams)) newUf, err := ufile.NewUFile(config.BasePath, 1*time.Minute) if err != nil { return err } // 出错退出时关闭 UFile defer func() { if rerr != nil { newUf.Close() } }() // 循环处理每个线路 for _, c := range config.UpStreams { pc, err := proxyclient.NewProxyClient(c.ProxyUrl) if err != nil { rerr = fmt.Errorf("无法创建上级代理:%v", err) return } client := DialClient{ name: c.Name, dnsResolve: c.DnsResolve, pc: pc, dialCredit: c.Credit, sleep: time.Duration(c.Sleep) * time.Millisecond, correctDelay: time.Duration(c.CorrectDelay) * time.Millisecond, whiteList: domains.NewDomains(100), blackList: domains.NewDomains(100), } // 循环处理每个黑白名单文件 // 添加到 ufile 里面,实际重新加载在 ufile 结果信道处处理。 flist := func(clientList []*ConfigDialClientWBList, wbList *domains.Domains) error { for _, f := range clientList { UpdateInterval, err := time.ParseDuration(f.UpdateInterval) if err != nil { return err } domainType, err := domains.ParseDomainType(f.Type) if err != nil { return err } userdara := ufUserdata{ name: fmt.Sprintf("%v-%v", f.Type, f.Path), domainType: domainType, domains: wbList, } if err := newUf.Add(f.Path, UpdateInterval, &userdara); err != nil { return err } } return nil } if err := flist(c.Whitelist, client.whiteList); err != nil { rerr = err return } if err := flist(c.Blacklist, client.blackList); err != nil { rerr = err return } newClients = append(newClients, &client) } d.rwm.Lock() defer d.rwm.Unlock() d.clients = newClients if d.uf != nil { d.uf.Close() } d.uf = newUf go d.loop(newUf) return nil }
// 更新配置 // hosts 本地文件会直接载入 // 不存在时打印警告,但是不出错退出,等新建 hosts 文件时将会自动载入 // hosts http、https 文件,定时更新。 // 每次配置重新载入所有的配置文件,并不是函数返回配置就立刻生效,配置生效需要时间。 func (h *hostsDns) Config(c *DnschanHostsConfig) error { newUFile, err := ufile.NewUFile(c.BashPath, hostsCheckInterval) if err != nil { return err } for _, hosts := range c.Hostss { // 解析更新间隔 updateInterval, err := time.ParseDuration(hosts.UpdateInterval) if err != nil { newUFile.Close() return fmt.Errorf("hosts 配置错误:updateInterval %v 格式不是正确的时间格式:%v", hosts.UpdateInterval, err) } // 类型 var domainType domains.DomainType switch strings.TrimSpace(strings.ToLower(hosts.Type)) { case "base": domainType = domains.Base case "suffix": domainType = domains.Suffix case "pan": domainType = domains.Pan case "regex": domainType = domains.Regex default: newUFile.Close() return fmt.Errorf("未知的 hosts 类型:%v", hosts.Type) } // userdata name := fmt.Sprint(domainType, "-", hosts.Credit, "-", hosts.Path) userdata := ufileUserdata{ name: name, domainType: domainType, credit: hosts.Credit, } if err := newUFile.Add(hosts.Path, updateInterval, &userdata); err != nil { newUFile.Close() return err } } // 配置没有明显错误,使用新配置 h.rwm.Lock() defer h.rwm.Unlock() if h.uf != nil { h.uf.Close() //关闭老配置的自动更新 } newDomains := domains.NewDomains(hostsCacheSize) h.ds = newDomains h.uf = newUFile go h.loop(newUFile, newDomains) return nil }