forked from gh-tt/cloudflare-scanner
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutil.go
149 lines (133 loc) · 3.53 KB
/
util.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package main
import (
"fmt"
"io/ioutil"
"math/rand"
"net/http"
"net/url"
"os"
"sort"
"strconv"
"strings"
"time"
)
const defaultTcpPort = 443
const tcpConnectTimeout = time.Millisecond * 450
const failTime = 4
type CloudflareIPData struct {
ip string
pingTime float64
pingCount int
pingReceived int
recvRate float64
downloadSpeed float64
}
func (cf *CloudflareIPData) getRecvRate() float64 {
if cf.recvRate == 0 {
cf.recvRate = float64(cf.pingReceived) / float64(cf.pingCount) * 100
}
return cf.recvRate
}
func convertExportData(data []CloudflareIPData) [][]string {
result := make([][]string, 0)
for _, v := range data {
result = append(result, v.toString())
}
return result
}
func (cf *CloudflareIPData) toString() []string {
result := make([]string, 6)
result[0] = cf.ip
result[1] = strconv.Itoa(cf.pingCount)
result[2] = strconv.Itoa(cf.pingReceived)
result[3] = strconv.FormatFloat(cf.getRecvRate(), 'f', 2, 64)
result[4] = strconv.FormatFloat(cf.pingTime, 'f', 2, 64)
result[5] = strconv.FormatFloat(cf.downloadSpeed, 'f', 2, 64)
return result
}
func ExportTxt(filepath string, data []CloudflareIPData) {
if len(data) > Conf.outputCount {
data = data[:Conf.outputCount]
}
exportData := convertExportData(data)
t := time.Now()
str := fmt.Sprintln(exportData, " --- ", t.Format("2006-01-02 15:04:05"))
if !Conf.isOutputTxt {
fmt.Println(str)
return
}
txt, err := os.OpenFile(filepath, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0660)
if err != nil {
fmt.Println("open result file err:", err)
return
}
defer txt.Close()
n, err := txt.WriteString(str)
if err != nil {
fmt.Println("export result err: ", err, " len=", n)
}
}
func filterIpData(data []CloudflareIPData) (res []CloudflareIPData) {
sort.Slice(data, func(i, j int) bool {
if data[i].getRecvRate() != data[j].getRecvRate() {
return data[i].getRecvRate() > data[j].getRecvRate()
}
return data[i].pingTime < data[j].pingTime
})
for _, v := range data {
if v.pingTime <= Conf.rttLimit && v.recvRate >= Conf.recvRateLimit {
res = append(res, v)
}
}
return
}
func loadIp() []string {
buf, err := ioutil.ReadFile(Conf.ipFilename)
if err != nil {
fmt.Println("read ip file err", err)
panic(err)
}
ips := strings.Split(string(buf), "\n")
ips = ips[:len(ips)-1]
ipList := make([]string, 0)
count := Conf.selectCountEveryIp
if count <= 0 || count > 255 {
panic("每个ip段选择的ip数量,不能为0且小于等于255")
}
rand.Seed(time.Now().UnixNano())
for _, v := range ips {
ip := strings.Split(v, ".")
for i := 0; i < count; i++ {
num := rand.Intn(254) + 1
ipList = append(ipList, fmt.Sprintf("%s.%s.%s.%v", ip[0], ip[1], ip[2], num))
}
}
return ipList
}
func sortBySpeedAndModifyDns(data []CloudflareIPData) {
if len(data) == 0 {
return
}
sort.Slice(data, func(i, j int) bool {
return data[i].downloadSpeed > data[j].downloadSpeed
})
if !DnsConf.modifyEnable {
fmt.Println("不需要修改dns")
return
}
ip := data[0].ip
form := make(url.Values)
form["login_token"] = []string{DnsConf.dnspodToken}
form["domain"] = []string{DnsConf.domain}
form["sub_domain"] = []string{DnsConf.subDomain}
form["record_id"] = []string{DnsConf.recordId}
form["record_type"] = []string{DnsConf.recordType}
form["record_line"] = []string{DnsConf.recordLine}
form["value"] = []string{ip}
if data[0].downloadSpeed >= DnsConf.speedLimit {
_, _ = http.PostForm("https://dnsapi.cn/Record.Modify", form)
fmt.Println("修改dns成功")
} else {
fmt.Println("ip不符合要求,修改dns失败:", ip)
}
}