forked from XIU2/CloudflareSpeedTest
-
Notifications
You must be signed in to change notification settings - Fork 4
/
main.go
177 lines (152 loc) · 7.1 KB
/
main.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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
package main
import (
"encoding/json"
"flag"
"fmt"
"net/http"
"os"
"runtime"
"time"
"github.com/Ptechgithub/CloudflareScanner/task"
"github.com/Ptechgithub/CloudflareScanner/utils"
)
var (
version, versionNew string
)
func init() {
var printVersion bool
var help = `
CloudflareScanner ` + version + `
Test the latency and speed of all IP addresses of Cloudflare CDN, and get the fastest IP (IPv4+IPv6)!
https://github.com/Ptechgithub/CloudflareScanner
Options:
-n 200
Latency test threads; more threads lead to faster latency testing, do not set too high for low-performance devices (e.g., routers); (default 200, maximum 1000)
-t 4
Latency test times; number of times to test latency for a single IP; (default 4 times)
-dn 10
Download test count; after latency testing and sorting, number of IPs to test download speed from lowest latency; (default 10)
-dt 10
Download test time; maximum time for download speed test of a single IP, should not be too short; (default 10 seconds)
-tp 443
Specify test port; port used for latency test/download test; (default port 443)
-url https://speed.cloudflare.com/__down?bytes=52428800
Specify test address; address used for latency test (HTTPing)/download test, default address is not guaranteed to be available, it is recommended to self-host;
-httping
Switch test mode; switch latency test mode to HTTP protocol, test address used is from [-url] parameter; (default TCPing)
-httping-code 200
Valid status code; valid HTTP status code returned during HTTPing latency test, only one is allowed; (default 200 301 302)
-cfcolo HKG,KHH,NRT,LAX,SEA,SJC,FRA,MAD
Match specified region; region name is local airport code, separated by English comma, only available in HTTPing mode; (default all regions)
-tl 200
Maximum average latency; only output IPs with latency lower than specified maximum average latency, various upper and lower limit conditions can be combined; (default 9999 ms)
-tll 40
Minimum average latency; only output IPs with latency higher than specified minimum average latency; (default 0 ms)
-tlr 0.2
Maximum loss rate; only output IPs with loss rate lower than/equal to specified loss rate, range 0.00~1.00, 0 filters out any loss IPs; (default 1.00)
-sl 5
Minimum download speed; only output IPs with download speed higher than specified download speed, stop testing when enough IPs are gathered [-dn]; (default 0.00 MB/s)
-p 10
Display result count; directly display specified number of results after testing, when 0, results are not displayed and program exits; (default 10)
-f ip.txt
IP range data file; if path contains spaces, please enclose in quotes; supports other CDN IP ranges; (default ip.txt)
-ip 1.1.1.1,2.2.2.2/24,2606:4700::/32
Specify IP range data; specify IP range data to be tested directly through parameters, separated by English comma; (default none)
-o result.csv
Write result file; if path contains spaces, please enclose in quotes; leave empty to not write to file [-o ""]; (default result.csv)
-dd
Disable download test; after disabling, test results are sorted by latency (default sorted by download speed); (default enabled)
-allip
Test all IPs; test each IP in IP range (IPv4 only) (default randomly test one IP in each /24 range)
-v
Print program version + check for updates
-h
Print help instructions
`
var minDelay, maxDelay, downloadTime int
var maxLossRate float64
flag.IntVar(&task.Routines, "n", 200, "Latency test threads")
flag.IntVar(&task.PingTimes, "t", 4, "Latency test times")
flag.IntVar(&task.TestCount, "dn", 10, "Download test count")
flag.IntVar(&downloadTime, "dt", 10, "Download test time")
flag.IntVar(&task.TCPPort, "tp", 443, "Specify test port")
flag.StringVar(&task.URL, "url", "https://speed.cloudflare.com/__down?bytes=52428800", "Specify test address")
flag.BoolVar(&task.Httping, "httping", false, "Switch test mode")
flag.IntVar(&task.HttpingStatusCode, "httping-code", 0, "Valid status code")
flag.StringVar(&task.HttpingCFColo, "cfcolo", "", "Match specified region")
flag.IntVar(&maxDelay, "tl", 9999, "Maximum average latency")
flag.IntVar(&minDelay, "tll", 0, "Minimum average latency")
flag.Float64Var(&maxLossRate, "tlr", 1, "Maximum loss rate")
flag.Float64Var(&task.MinSpeed, "sl", 0, "Minimum download speed")
flag.IntVar(&utils.PrintNum, "p", 10, "Display result count")
flag.StringVar(&task.IPFile, "f", "ip.txt", "IP range data file")
flag.StringVar(&task.IPText, "ip", "", "Specify IP range data")
flag.StringVar(&utils.Output, "o", "result.csv", "Output result file")
flag.BoolVar(&task.Disable, "dd", false, "Disable download test")
flag.BoolVar(&task.TestAll, "allip", false, "Test all IPs")
flag.BoolVar(&printVersion, "v", false, "Print program version")
flag.Usage = func() { fmt.Print(help) }
flag.Parse()
if task.MinSpeed > 0 && time.Duration(maxDelay)*time.Millisecond == utils.InputMaxDelay {
fmt.Println("[Tip] When using [-sl] parameter, it is recommended to use [-tl] parameter to avoid continuous testing due to insufficient number of [-dn]...")
}
utils.InputMaxDelay = time.Duration(maxDelay) * time.Millisecond
utils.InputMinDelay = time.Duration(minDelay) * time.Millisecond
utils.InputMaxLossRate = float32(maxLossRate)
task.Timeout = time.Duration(downloadTime) * time.Second
task.HttpingCFColomap = task.MapColoMap()
if printVersion {
println(version)
fmt.Println("Checking for updates...")
checkUpdate()
if versionNew != "" {
fmt.Printf("*** Found new version [%s]! Please go to [https://github.com/Ptechgithub/CloudflareScanner] to update! ***", versionNew)
} else {
fmt.Println("Current version is the latest [" + version + "]!")
}
os.Exit(0)
}
}
func main() {
task.InitRandSeed() // Set random seed
fmt.Printf("# Ptechgithub/CloudflareScanner %s \n\n", version)
// Start latency testing + filter delay/loss
pingData := task.NewPing().Run().FilterDelay().FilterLossRate()
// Start download speed testing
speedData := task.TestDownloadSpeed(pingData)
utils.ExportCsv(speedData) // Export to file
speedData.Print() // Print results
if versionNew != "" {
fmt.Printf("\n*** Found New Version [%s]! Please go to [https://github.com/Ptechgithub/CloudflareScanner] to update! ***\n", versionNew)
}
endPrint()
}
func endPrint() {
if utils.NoPrintResult() {
return
}
if runtime.GOOS == "windows" { // If Windows, need to press Enter or Ctrl+C to exit (avoids closing after completion when run by double-clicking)
fmt.Printf("Press Enter or Ctrl+C to exit.")
fmt.Scanln()
}
}
// Check for updates
func checkUpdate() {
timeout := 10 * time.Second
client := http.Client{Timeout: timeout}
res, err := client.Get("https://api.github.com/repos/Ptechgithub/CloudflareScanner/releases/latest")
if err != nil {
return
}
defer res.Body.Close()
var release struct {
TagName string `json:"tag_name"`
}
err = json.NewDecoder(res.Body).Decode(&release)
if err != nil {
return
}
if release.TagName != version {
versionNew = release.TagName
}
}