From d621095e14ff8c6fdaaadc409b8dff32cfc39e78 Mon Sep 17 00:00:00 2001 From: GuanM <1-GuanM@users.noreply.gitlab.54sxh.cn> Date: Wed, 19 Jun 2024 01:13:53 +0800 Subject: [PATCH] =?UTF-8?q?IP=E8=8E=B7=E5=8F=96=E6=96=B9=E5=BC=8F=E5=AE=8C?= =?UTF-8?q?=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- task/ip.go | 93 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 55 insertions(+), 38 deletions(-) diff --git a/task/ip.go b/task/ip.go index 17a7057..fdce327 100644 --- a/task/ip.go +++ b/task/ip.go @@ -4,10 +4,11 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "math/rand" "net" "net/http" + "sort" + "strings" "time" ) @@ -31,16 +32,20 @@ var ( } IPCidrApi = "https://api.cloudflare.com/client/v4/ips" IsOff = false + MaxMS int + MinMS int + TestAll = false + randGen *rand.Rand ) type IPRangeList struct { Ips []*net.IPAddr unusedIpCount int - delays []IPDelay + Delays []IPDelay } -func init() { - rand.Seed(time.Now().UnixNano()) +func InitRandSeed() { + randGen = rand.New(rand.NewSource(time.Now().UnixNano())) } // CreateData 从IP列表中选择一定数量的IP返回 @@ -49,45 +54,26 @@ func CreateData() *IPRangeList { return &IPRangeList{ Ips: ips, unusedIpCount: 0, - delays: []IPDelay{}, + Delays: []IPDelay{}, } } // loadIPRanges 从CIDR列表中加载IP地址 -func loadIPRanges(ciders []string) []*net.IPAddr { - var ipAddresses []*net.IPAddr - for _, cidr := range ciders { - _, ipnet, err := net.ParseCIDR(cidr) - if err != nil { - fmt.Printf("解析CIDR %s 时出错: %v\n", cidr, err) +func loadIPRanges(ipList []string) []*net.IPAddr { + ranges := newIPRanges() + for _, ip := range ipList { + line := strings.TrimSpace(ip) // 去除首尾的空白字符(空格、制表符、换行符等) + if line == "" { // 跳过空行 continue } - // 计算给定IPNet的范围 - ones, _ := ipnet.Mask.Size() - if ones > 24 { - fmt.Printf("CIDR %s 小于 /24\n", cidr) - continue - } - numSubnets := 1 << (24 - ones) - for i := 0; i < numSubnets; i++ { - ip := generateRandomIP(ipnet, i) - ipAddresses = append(ipAddresses, ip) + ranges.parseCIDR(line) // 解析 IP 段,获得 IP、IP 范围、子网掩码 + if IsIpv4(line) { // 生成要测速的所有 IPv4 / IPv6 地址(单个/随机/全部) + ranges.chooseIPv4() + } else { + ranges.chooseIPv6() } } - return ipAddresses -} - -// generateRandomIP 在给定IPNet范围内生成随机IP地址 -func generateRandomIP(ipnet *net.IPNet, subnetIndex int) *net.IPAddr { - ip := ipnet.IP.To4() - if ip == nil { - return nil - } - // 设置第三个字节为子网索引 - ip[2] = ip[2] + byte(subnetIndex) - // 为最后一个字节生成随机值 - ip[3] = byte(rand.Intn(256)) - return &net.IPAddr{IP: ip} + return ranges.ips } // GetIPv4List 获取IPv4 CIDR列表 @@ -107,7 +93,7 @@ func GetIPv4List() []string { }(resp.Body) // 读取响应主体 - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { fmt.Println("获取在线列表失败,正在使用内置列表") return Ipv4Cidr @@ -121,7 +107,7 @@ func GetIPv4List() []string { Success bool `json:"success"` } - if err := json.Unmarshal(body, &data); err != nil || !data.Success { + if err = json.Unmarshal(body, &data); err != nil || !data.Success { fmt.Println("获取在线列表失败,正在使用内置列表") return Ipv4Cidr } @@ -130,7 +116,38 @@ func GetIPv4List() []string { return data.Result.IPv4CIDRs } +// ExcludeInvalid 排除不合格节点 +func (p *IPRangeList) ExcludeInvalid() []IPDelay { + // 初始化一个空IPDelay切片 + var delays []IPDelay + // 遍历IPRangeList的Delays切片 + for ip, delay := range p.Delays { + // 如果最大延迟大于0且小于最大延迟 + if MaxMS > 0 && delay.Delay > time.Duration(MaxMS)*time.Millisecond { + continue + } + // 如果最小延迟大于0且大于最小延迟 + if MinMS > 0 && delay.Delay < time.Duration(MinMS)*time.Millisecond { + continue + } + // 将IPDelay的IP和Delay添加到delays切片中 + delays = append(delays, IPDelay{IP: p.Ips[ip], Delay: delay.Delay, DownloadSpeed: 0}) + } + return delays +} + +// SortNodesDesc 按延迟降序排列 +func SortNodesDesc(p []IPDelay) []IPDelay { + sorted := make([]IPDelay, len(p)) + _ = copy(sorted, p) + // 使用sort.Slice 对切片进行排序 + sort.Slice(sorted, func(i, j int) bool { + return sorted[i].Delay < sorted[j].Delay + }) + return sorted +} + // IsIpv4 检查IP地址是否为IPv4 func IsIpv4(ip string) bool { - return net.ParseIP(ip) != nil + return strings.Contains(ip, ".") }