diff --git a/main.go b/main.go index fe82167..1beac0f 100644 --- a/main.go +++ b/main.go @@ -95,8 +95,8 @@ https://github.com/XIU2/CloudflareSpeedTest func main() { go checkUpdate() // 检查版本更新 - initRandSeed() // 置随机数种子 - ips := loadFirstIPOfRangeFromFile(task.IPFile) // 读入IP + ips := task.LoadIPRanges() + // ips := loadFirstIPOfRangeFromFile(task.IPFile) // 读入IP // 开始延迟测速 fmt.Printf("# XIU2/CloudflareSpeedTest %s \n", version) @@ -123,48 +123,6 @@ func main() { var pause int fmt.Scanln(&pause) } - - // control := make(chan bool, pingRoutine) - // for _, ip := range ips { - // wg.Add(1) - // control <- false - // handleProgress := handleProgressGenerator(bar) // 多线程进度条 - // go tcpingGoroutine(&wg, &mu, ip, tcpPort, pingTime, &data, control, handleProgress) - // } - // wg.Wait() - // bar.Finish() - // data := ping.Data() - // sort.Sort(utils.CloudflareIPDataSet(data)) - // sort.Sort(CloudflareIPDataSet(data)) // 排序(按延迟,从低到高,不同丢包率会分开单独按延迟和丢包率排序) - - // 延迟测速完毕后,以 [平均延迟上限] + [平均延迟下限] 条件过滤结果 - // if timeLimit != 9999 || timeLimitLow != 0 { - // for i := 0; i < len(data); i++ { - // if float64(data[i].pingTime) > timeLimit { // 平均延迟上限 - // break - // } - // if float64(data[i].pingTime) <= timeLimitLow { // 平均延迟下限 - // continue - // } - // data2 = append(data2, data[i]) // 延迟满足条件时,添加到新数组中 - // } - // data = data2 - // data2 = []CloudflareIPData{} - // } - - // 开始下载测速 - // if !disableDownload { // 如果禁用下载测速就跳过 - // testDownloadSpeed(data, data2, bar) - // } - - // if len(data2) > 0 { // 如果该数组有内容,说明指定了 [下载测速下限] 条件,且最少有 1 个满足条件的 IP - // data = data2 - // } - // sort.Sort(CloudflareIPDataSetD(data)) // 排序(按下载速度,从高到低) - // if outputFile != "" { - // ExportCsv(outputFile, data) // 输出结果到文件 - // } - // printResult(data) // 显示最快结果 } // 检查更新 diff --git a/task/download.go b/task/download.go index 072c615..bff3502 100644 --- a/task/download.go +++ b/task/download.go @@ -67,7 +67,7 @@ func TestDownloadSpeed(ipSet utils.PingDelaySet) (sppedSet utils.DownloadSpeedSe fmt.Printf("开始下载测速(下载速度下限:%.2f MB/s,下载测速数量:%d,下载测速队列:%d):\n", MinSpeed, TestCount, testNum) bar := utils.NewBar(TestCount) for i := 0; i < testNum; i++ { - speed := downloadSpeedHandler(&ipSet[i].IP) + speed := downloadSpeedHandler(ipSet[i].IP) ipSet[i].DownloadSpeed = speed // 在每个 IP 下载测速后,以 [下载速度下限] 条件过滤结果 if speed >= MinSpeed*1024*1024 { diff --git a/task/ip.go b/task/ip.go index c2ff808..d22af3c 100644 --- a/task/ip.go +++ b/task/ip.go @@ -1,10 +1,210 @@ package task +import ( + "bufio" + "log" + "math/rand" + "net" + "os" + "strconv" + "strings" + "time" +) + +const defaultInputFile = "ip.txt" + var ( // IPv6 IP version is 6 IPv6 = false // TestAll test all ip TestAll = false // IPFile is the filename of IP Rangs - IPFile = "ip.txt" + IPFile = defaultInputFile ) + +func randipEndWith(num int) uint8 { + rand.Seed(time.Now().UnixNano()) + return uint8(rand.Intn(num)) +} + +func LoadIPRanges() []*net.IPAddr { + if IPFile == "" { + IPFile = defaultInputFile + } + file, err := os.Open(IPFile) + if err != nil { + log.Fatal(err) + } + defer file.Close() + firstIPs := make([]*net.IPAddr, 0) + scanner := bufio.NewScanner(file) + // scanner.Split(bufio.ScanLines) + for scanner.Scan() { + IPString := scanner.Text() + // 如果不含有 '/' 则代表不是 IP 段,而是一个单独的 IP,因此需要加上 /32 /128 子网掩码 + if !strings.Contains(IPString, "/") { + if IPv6 { + IPString += "/128" + } else { + IPString += "/32" + } + } + firstIP, IPRange, err := net.ParseCIDR(IPString) + // fmt.Println(firstIP) + // fmt.Println(IPRange) + if err != nil { + log.Fatal(err) + } + if IPv6 { + //IPv6 + loadIPv6(IPString, IPRange, firstIP, firstIPs) + continue + } + // IPv4 + minIP, maxIP, mask := getCidrIPRange(IPString) // 获取 IP 最后一段最小值和最大值 + maxIPNum := getCidrHostNum(mask) // 根据子网掩码获取主机数量 + for IPRange.Contains(firstIP) { + if TestAll { // 如果是测速全部 IP + for i := minIP; i <= maxIP; i++ { // 遍历 IP 最后一段最小值到最大值 + firstIP[15] = i + firstIPCopy := make([]byte, len(firstIP)) + copy(firstIPCopy, firstIP) + firstIPs = append(firstIPs, &net.IPAddr{IP: firstIPCopy}) + } + } else { // 随机 IP 的最后一段 0.0.0.X + firstIP[15] = minIP + randipEndWith(maxIPNum) + firstIPCopy := make([]byte, len(firstIP)) + copy(firstIPCopy, firstIP) + firstIPs = append(firstIPs, &net.IPAddr{IP: firstIPCopy}) + } + firstIP[14]++ // 0.0.(X+1).X + if firstIP[14] == 0 { + firstIP[13]++ // 0.(X+1).X.X + if firstIP[13] == 0 { + firstIP[12]++ // (X+1).X.X.X + } + } + } + + } + return firstIPs +} + +func loadIPv6(IPString string, IPRange *net.IPNet, firstIP net.IP, firstIPs []*net.IPAddr) { + var tempIP uint8 + for IPRange.Contains(firstIP) { + //fmt.Println(firstIP) + //fmt.Println(firstIP[0], firstIP[1], firstIP[2], firstIP[3], firstIP[4], firstIP[5], firstIP[6], firstIP[7], firstIP[8], firstIP[9], firstIP[10], firstIP[11], firstIP[12], firstIP[13], firstIP[14], firstIP[15]) + if !strings.Contains(IPString, "/128") { + firstIP[15] = randipEndWith(255) // 随机 IP 的最后一段 + firstIP[14] = randipEndWith(255) // 随机 IP 的最后一段 + } + firstIPCopy := make([]byte, len(firstIP)) + copy(firstIPCopy, firstIP) + firstIPs = append(firstIPs, &net.IPAddr{IP: firstIPCopy}) + tempIP = firstIP[13] + firstIP[13] += randipEndWith(255) + if firstIP[13] >= tempIP { + continue + } + tempIP = firstIP[12] + firstIP[12] += randipEndWith(255) + if firstIP[12] >= tempIP { + continue + } + tempIP = firstIP[11] + firstIP[11] += randipEndWith(255) + if firstIP[11] >= tempIP { + continue + } + tempIP = firstIP[10] + firstIP[10] += randipEndWith(255) + if firstIP[10] >= tempIP { + continue + } + tempIP = firstIP[9] + firstIP[9] += randipEndWith(255) + if firstIP[9] >= tempIP { + continue + } + tempIP = firstIP[8] + firstIP[8] += randipEndWith(255) + if firstIP[8] >= tempIP { + continue + } + tempIP = firstIP[7] + firstIP[7] += randipEndWith(255) + if firstIP[7] >= tempIP { + continue + } + tempIP = firstIP[6] + firstIP[6] += randipEndWith(255) + if firstIP[6] >= tempIP { + continue + } + tempIP = firstIP[5] + firstIP[5] += randipEndWith(255) + if firstIP[5] >= tempIP { + continue + } + tempIP = firstIP[4] + firstIP[4] += randipEndWith(255) + if firstIP[4] >= tempIP { + continue + } + tempIP = firstIP[3] + firstIP[3] += randipEndWith(255) + if firstIP[3] >= tempIP { + continue + } + tempIP = firstIP[2] + firstIP[2] += randipEndWith(255) + if firstIP[2] >= tempIP { + continue + } + tempIP = firstIP[1] + firstIP[1] += randipEndWith(255) + if firstIP[1] >= tempIP { + continue + } + tempIP = firstIP[0] + firstIP[0] += randipEndWith(255) + } +} + +// 根据子网掩码获取主机数量 +func getCidrHostNum(maskLen int) int { + cidrIPNum := int(0) + if maskLen < 32 { + var i int = int(32 - maskLen - 1) + for ; i >= 1; i-- { + cidrIPNum += 1 << i + } + cidrIPNum += 2 + } else { + cidrIPNum = 1 + } + if cidrIPNum > 255 { + cidrIPNum = 255 + } + return cidrIPNum +} + +// 获取 IP 最后一段最小值和最大值、子网掩码 +func getCidrIPRange(cidr string) (minIP, maxIP uint8, mask int) { + ipRange := strings.Split(cidr, "/") + ipSegs := strings.Split(ipRange[0], ".") + mask, _ = strconv.Atoi(ipRange[1]) + seg4, _ := strconv.Atoi(ipSegs[3]) + minIP, maxIP = getIPSegRange(uint8(seg4), uint8(32-mask)) + return +} + +// 根据输入的基础IP地址和CIDR掩码计算一个IP片段的区间 +func getIPSegRange(userSegIP, offset uint8) (uint8, uint8) { + var ipSegMax uint8 = 255 + netSegIP := ipSegMax << offset + segMinIP := netSegIP & userSegIP + segMaxIP := userSegIP&(255<