初始化保存 已完成IP列表获取

This commit is contained in:
GuanM 2024-06-18 20:10:51 +08:00
parent 7599fe83c4
commit 94c7b10209
6 changed files with 253 additions and 1 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/Run/
/.idea/

View File

@ -1,2 +1,19 @@
# DockerST
Docker官方源加速程序
本项目旨在于直接加速Docker官方源提高Docker镜像下载速度
Docker官方使用的是CloudFlare的CDN 优选CloudFlare IP后即可实现高速下载 进行原生加速
## 安装本程序
```bash
```
## 使用代理优选加速(推荐)
```bash
https://docker.sxh.workers.dev/
```
## 直接加速

3
go.mod Normal file
View File

@ -0,0 +1,3 @@
module DockerST
go 1.22

42
main.go Normal file
View File

@ -0,0 +1,42 @@
package main
import (
"DockerST/task"
"flag"
"fmt"
)
var (
VersionPrint bool
Version string
)
func init() {
// checkUpdate()
// 定义一个字符串类型的命令行标志
flag.IntVar(&task.TcpPort, "p", 443, "TCP端口")
flag.IntVar(&task.PingTimes, "t", 4, "Ping次数")
flag.IntVar(&task.Routines, "r", 200, "并发数")
flag.BoolVar(&VersionPrint, "v", false, "输出版本")
flag.BoolVar(&task.IsOff, "om", false, "是否为离线模式")
flag.Parse()
if VersionPrint {
fmt.Println("Version:", Version)
}
}
func main() {
if VersionPrint {
return
}
// 输出版本
fmt.Printf("# DockerST %s \n", Version)
_ = task.CreateData().Run()
}
func WriteHost(domain string, ip string) {
}
func checkUpdate() {
}

136
task/ip.go Normal file
View File

@ -0,0 +1,136 @@
package task
import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"math/rand"
"net"
"net/http"
"sync"
"time"
)
var (
Ipv4Cidr = []string{
"173.245.48.0/20",
"103.21.244.0/22",
"103.22.200.0/22",
"103.31.4.0/22",
"141.101.64.0/18",
"108.162.192.0/18",
"190.93.240.0/20",
"188.114.96.0/20",
"197.234.240.0/22",
"198.41.128.0/17",
"162.158.0.0/15",
"104.16.0.0/13",
"104.24.0.0/14",
"172.64.0.0/13",
"131.0.72.0/22",
}
IPCidrApi = "https://api.cloudflare.com/client/v4/ips"
IsOff = false
)
type IPRangeList struct {
Ips []*net.IPAddr
unusedIpCount int
wg sync.WaitGroup
}
func init() {
rand.Seed(time.Now().UnixNano())
}
// CreateData 从IP列表中选择一定数量的IP返回
func CreateData() *IPRangeList {
ips := loadIPRanges(GetIPv4List())
return &IPRangeList{
Ips: ips,
unusedIpCount: 0,
}
}
// 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)
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)
}
}
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}
}
// GetIPv4List 获取IPv4 CIDR列表
func GetIPv4List() []string {
// 离线变量
if IsOff {
return Ipv4Cidr
}
// 获取在线IPv4 CIDR列表
resp, err := http.Get(IPCidrApi)
if err != nil {
fmt.Println("获取在线列表失败,正在使用内置列表")
return Ipv4Cidr
}
defer func(Body io.ReadCloser) {
_ = Body.Close()
}(resp.Body)
// 读取响应主体
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("获取在线列表失败,正在使用内置列表")
return Ipv4Cidr
}
// 解析JSON数据
var data struct {
Result struct {
IPv4CIDRs []string `json:"ipv4_cidrs"`
} `json:"result"`
Success bool `json:"success"`
}
if err := json.Unmarshal(body, &data); err != nil || !data.Success {
fmt.Println("获取在线列表失败,正在使用内置列表")
return Ipv4Cidr
}
fmt.Println("获取在线列表成功,正在使用在线列表")
return data.Result.IPv4CIDRs
}
// IsIpv4 检查IP地址是否为IPv4
func IsIpv4(ip string) bool {
return net.ParseIP(ip) != nil
}

52
task/tcpping.go Normal file
View File

@ -0,0 +1,52 @@
package task
import (
"fmt"
"net"
"time"
)
var (
TcpPort = 443
PingTimes = 4
Routines = 200
TcpConnectTimeOut = time.Second * 1
)
func (p *IPRangeList) Run() *IPRangeList {
ch := make(chan struct{}, Routines)
for _, ip := range p.Ips {
p.wg.Add(1)
ch <- struct{}{} // 控制最大并发数
go func(ip *net.IPAddr) {
defer p.wg.Done()
defer func() { <-ch }() // 释放并发控制
success, duration := TCPing(ip)
if success {
p.unusedIpCount++
} else {
// 删除
}
fmt.Printf("IP: %s, Success: %t, Duration: %v\n", ip.String(), success, duration)
}(ip)
}
// 多线程执行
return p
}
func TCPing(ip *net.IPAddr) (bool, time.Duration) {
startTime := time.Now()
var fullAddress string
if IsIpv4(ip.String()) {
fullAddress = fmt.Sprintf("%s:%d", ip.String(), TcpPort)
} else {
fullAddress = fmt.Sprintf("[%s]:%d", ip.String(), TcpPort)
}
conn, err := net.DialTimeout("tcp", fullAddress, TcpConnectTimeOut)
if err != nil {
return false, 0
}
defer conn.Close()
duration := time.Since(startTime)
return true, duration
}