package toolinstaller import ( "net/http" "sync" "time" ) // ============================================ // 网络环境检测 — 多端点交叉验证判断是否在中国网络内 // 原理:Google/YouTube 在中国被墙,阿里云/清华镜像仅国内可达 // 4 条线路 ≥3 条一致才判定,防止单点故障误判 // ============================================ // chinaEndpoint 检测端点定义 type chinaEndpoint struct { URL string // 检测 URL Name string // 端点名称(日志用) Timeout time.Duration // 超时时间 // 在中国网络内的预期可达性 ReachableInChina bool } var chinaEndpoints = []chinaEndpoint{ {URL: "https://www.google.com", Name: "Google", Timeout: 2 * time.Second, ReachableInChina: false}, {URL: "https://www.youtube.com", Name: "YouTube", Timeout: 2 * time.Second, ReachableInChina: false}, {URL: "https://www.baidu.com", Name: "Baidu", Timeout: 2 * time.Second, ReachableInChina: true}, {URL: "https://mirrors.aliyun.com", Name: "Aliyun", Timeout: 3 * time.Second, ReachableInChina: true}, {URL: "https://mirrors.tuna.tsinghua.edu.cn", Name: "Tsinghua", Timeout: 3 * time.Second, ReachableInChina: true}, } var ( networkChecked bool networkMu sync.Mutex isChina bool ) // IsChinaNetwork 检测当前是否在中国网络环境。 // 使用 5 个端点交叉验证:Google/YouTube 不可达 + 百度/阿里云/清华可达 → 判定为国内。 // 检测结果缓存,后续调用直接返回缓存值。 func IsChinaNetwork() bool { networkMu.Lock() defer networkMu.Unlock() if networkChecked { return isChina } // 并发检测所有端点 type result struct { name string reachable bool } results := make([]result, len(chinaEndpoints)) var wg sync.WaitGroup for i, ep := range chinaEndpoints { wg.Add(1) go func(idx int, endpoint chinaEndpoint) { defer wg.Done() client := &http.Client{Timeout: endpoint.Timeout} resp, err := client.Head(endpoint.URL) reachable := err == nil && resp != nil && resp.StatusCode < 500 if resp != nil { resp.Body.Close() } results[idx] = result{name: endpoint.Name, reachable: reachable} }(i, ep) } wg.Wait() // 统计:预期不可达(国外)vs 预期可达(国内) var foreignUnreachable, domesticReachable int for i, r := range results { ep := chinaEndpoints[i] if ep.ReachableInChina { if r.reachable { domesticReachable++ } } else { if !r.reachable { foreignUnreachable++ } } } // 判定逻辑:国外端点全部不可达 && 国内端点至少 2 个可达 isChina = foreignUnreachable >= 2 && domesticReachable >= 2 networkChecked = true return isChina } // ResetNetworkCheck 重置网络检测缓存(用于网络环境变化后重新检测) func ResetNetworkCheck() { networkMu.Lock() defer networkMu.Unlock() networkChecked = false isChina = false }