mirror of
				https://github.com/oneclickvirt/ecs.git
				synced 2025-10-31 02:46:40 +08:00 
			
		
		
		
	Compare commits
	
		
			14 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | a70dc2bab1 | ||
|   | 5041a16a9a | ||
| ![github-actions[bot]](/assets/img/avatar_default.png)  | 21deb3587e | ||
|   | 3bac30edc2 | ||
| ![github-actions[bot]](/assets/img/avatar_default.png)  | 9ef2ec4a9e | ||
|   | ac33e00e0a | ||
|   | 7a439f7095 | ||
|   | e3bfa65f66 | ||
|   | 74e33a212c | ||
|   | bba8595033 | ||
|   | 530181be87 | ||
| ![github-actions[bot]](/assets/img/avatar_default.png)  | 7deb986209 | ||
|   | ea8e5efbd3 | ||
|   | db88ee8479 | 
							
								
								
									
										2
									
								
								.github/workflows/main.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/main.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -46,7 +46,7 @@ jobs: | ||||
|           if [[ "$GITHUB_REF" == refs/tags/* ]]; then | ||||
|             VERSION="${GITHUB_REF#refs/tags/v}" | ||||
|           else | ||||
|             VERSION=$(git describe --tags --abbrev=0 2>/dev/null | sed 's/^v//' || echo "0.1.36") | ||||
|             VERSION=$(git describe --tags --abbrev=0 2>/dev/null | sed 's/^v//' || echo "0.1.37") | ||||
|           fi | ||||
|           echo "Using version: $VERSION" | ||||
|           FILE="goecs.sh" | ||||
|   | ||||
| @@ -6,7 +6,9 @@ builds: | ||||
|     env: | ||||
|       - CGO_ENABLED=0 | ||||
|     ldflags: | ||||
|       - -s -w -X main.version={{.Version}} -X main.arch={{.Arch}} -checklinkname=0 | ||||
|       - -s -w -X main.version={{.Version}} -X main.arch={{.Arch}} -checklinkname=0 -extldflags=-static | ||||
|     flags: | ||||
|       - -trimpath | ||||
|     goos: | ||||
|       - linux | ||||
|       - windows | ||||
| @@ -34,6 +36,8 @@ builds: | ||||
|       - CXX=o64-clang++ | ||||
|     ldflags: | ||||
|       - -s -w -X main.version={{.Version}} -X main.arch={{.Arch}} -checklinkname=0 | ||||
|     flags: | ||||
|       - -trimpath | ||||
|     goos: | ||||
|       - darwin | ||||
|     goarch: | ||||
| @@ -47,6 +51,8 @@ builds: | ||||
|       - CXX=oa64-clang++ | ||||
|     ldflags: | ||||
|       - -s -w -X main.version={{.Version}} -X main.arch={{.Arch}} -checklinkname=0 | ||||
|     flags: | ||||
|       - -trimpath | ||||
|     goos: | ||||
|       - darwin | ||||
|     goarch: | ||||
| @@ -75,4 +81,4 @@ changelog: | ||||
|       - Merge pull request | ||||
|       - Merge branch | ||||
|       - go mod tidy | ||||
|       - New translations | ||||
|       - New translations | ||||
|   | ||||
							
								
								
									
										26
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,6 +1,8 @@ | ||||
| # ECS | ||||
|  | ||||
| [](https://github.com/oneclickvirt/ecs/actions/workflows/main.yaml)  | ||||
| [](https://github.com/oneclickvirt/ecs/actions/workflows/main.yaml) | ||||
|  | ||||
| [](https://app.fossa.com/projects/git%2Bgithub.com%2Foneclickvirt%2Fecs?ref=badge_shield) | ||||
|  | ||||
| [](https://hits.spiritlhl.net) | ||||
|  | ||||
| @@ -137,19 +139,19 @@ Shell 版本:[https://github.com/spiritLHLS/ecs](https://github.com/spiritLHLS | ||||
|    export noninteractive=true && ./goecs.sh env | ||||
|    ``` | ||||
|  | ||||
| 3. **安装 `goecs`** | ||||
| 3. **安装 `goecs` 本体(仅下载二进制文件无依赖安装)** | ||||
|  | ||||
|    ```bash | ||||
|    ./goecs.sh install | ||||
|    ``` | ||||
|  | ||||
| 4. **升级 `goecs`** | ||||
| 4. **升级 `goecs` 本体** | ||||
|  | ||||
|    ```bash | ||||
|    ./goecs.sh upgrade | ||||
|    ``` | ||||
|  | ||||
| 5. **卸载 `goecs`** | ||||
| 5. **卸载 `goecs` 本体** | ||||
|  | ||||
|    ```bash | ||||
|    ./goecs.sh uninstall | ||||
| @@ -341,6 +343,7 @@ GOOS=darwin GOARCH=amd64 go build -o goecs_darwin | ||||
| | 测试稳定性       | 核心测试组件10年以上未变 | 每个大版本更新测试项,分数不同版本间难以对比(每个版本对标当前最好的CPU) | | ||||
| | 测试内容         | 仅测试计算性能 | 覆盖多种性能测试,分数加权计算,但部分测试实际不常用 | | ||||
| | 适用场景         | 适合快速测试,仅测试计算性能 | 适合综合全面的测试 | | ||||
| | 排行榜         | [sysbench.spiritlhl.net](https://sysbench.spiritlhl.net/) | [browser.geekbench.com](https://browser.geekbench.com/) | | ||||
|  | ||||
| 且```goecs```测试使用何种CPU测试方式可使用参数指定,默认只是为了更多用户快速测试的需求 | ||||
|  | ||||
| @@ -371,7 +374,7 @@ GOOS=darwin GOARCH=amd64 go build -o goecs_darwin | ||||
| 感谢 | ||||
|  | ||||
| <a href="https://h501.io/?from=69" target="_blank"> | ||||
|   <img src="https://github.com/spiritLHLS/ecs/assets/103393591/dfd47230-2747-4112-be69-b5636b34f07f" alt="h501"> | ||||
|   <img src="https://github.com/spiritLHLS/ecs/assets/103393591/dfd47230-2747-4112-be69-b5636b34f07f" alt="h501" style="height: 50px;"> | ||||
| </a> | ||||
|  | ||||
| 提供的免费托管支持本开源项目的共享测试结果存储 | ||||
| @@ -379,13 +382,20 @@ GOOS=darwin GOARCH=amd64 go build -o goecs_darwin | ||||
| 同时感谢以下平台提供编辑和测试支持 | ||||
|  | ||||
| <a href="https://www.jetbrains.com/go/" target="_blank"> | ||||
|   <img src="https://resources.jetbrains.com/storage/products/company/brand/logos/GoLand.png" alt="goland"> | ||||
|   <img src="https://resources.jetbrains.com/storage/products/company/brand/logos/GoLand.png" alt="goland" style="height: 50px;"> | ||||
| </a> | ||||
|  | ||||
| <a href="https://community.ibm.com/zsystems/form/l1cc-oss-vm-request/" target="_blank"> | ||||
|   <img src="https://linuxone.cloud.marist.edu/oss/resources/images/linuxonelogo03.png" alt="ibm"> | ||||
|   <img src="https://linuxone.cloud.marist.edu/oss/resources/images/linuxonelogo03.png" alt="ibm" style="height: 50px;"> | ||||
| </a> | ||||
|  | ||||
| <a href="https://console.zmto.com/?affid=1524" target="_blank"> | ||||
|   <img src="https://console.zmto.com/templates/2019/dist/images/logo_dark.svg" alt="zmto" style="height: 50px;"> | ||||
| </a> | ||||
|  | ||||
| ## Stargazers over time | ||||
|  | ||||
| [](https://www.spiritlhl.net) | ||||
| [](https://www.spiritlhl.net) | ||||
|  | ||||
| ## License | ||||
| [](https://app.fossa.com/projects/git%2Bgithub.com%2Foneclickvirt%2Fecs?ref=badge_large) | ||||
							
								
								
									
										10
									
								
								README_EN.md
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								README_EN.md
									
									
									
									
									
								
							| @@ -368,7 +368,7 @@ Thank [he.net](https://he.net) [bgp.tools](https://bgp.tools) [ipinfo.io](https: | ||||
| Thank | ||||
|  | ||||
| <a href="https://h501.io/?from=69" target="_blank"> | ||||
|   <img src="https://github.com/spiritLHLS/ecs/assets/103393591/dfd47230-2747-4112-be69-b5636b34f07f" alt="h501"> | ||||
|   <img src="https://github.com/spiritLHLS/ecs/assets/103393591/dfd47230-2747-4112-be69-b5636b34f07f" alt="h501" style="height: 50px;"> | ||||
| </a> | ||||
|  | ||||
| provided free hosting support for this open source project's shared test results storage | ||||
| @@ -376,11 +376,15 @@ provided free hosting support for this open source project's shared test results | ||||
| Thanks also to the following platforms for editorial and testing support | ||||
|  | ||||
| <a href="https://www.jetbrains.com/go/" target="_blank"> | ||||
|   <img src="https://resources.jetbrains.com/storage/products/company/brand/logos/GoLand.png" alt="goland"> | ||||
|   <img src="https://resources.jetbrains.com/storage/products/company/brand/logos/GoLand.png" alt="goland" style="height: 50px;"> | ||||
| </a> | ||||
|  | ||||
| <a href="https://community.ibm.com/zsystems/form/l1cc-oss-vm-request/" target="_blank"> | ||||
|   <img src="https://linuxone.cloud.marist.edu/oss/resources/images/linuxonelogo03.png" alt="ibm"> | ||||
|   <img src="https://linuxone.cloud.marist.edu/oss/resources/images/linuxonelogo03.png" alt="ibm" style="height: 50px;"> | ||||
| </a> | ||||
|  | ||||
| <a href="https://console.zmto.com/?affid=1524" target="_blank"> | ||||
|   <img src="https://console.zmto.com/templates/2019/dist/images/logo_dark.svg" alt="zmto" style="height: 50px;"> | ||||
| </a> | ||||
|  | ||||
| ## Stargazers over time | ||||
|   | ||||
| @@ -110,6 +110,8 @@ AMD的7950x单核满血性能得分在6500左右,AMD的5950x单核满血性能 | ||||
|  | ||||
| 有时候多核得分和单核得分一样,证明商家在限制程序并发使用CPU,典型例子腾讯云。 | ||||
|  | ||||
| ```Sysbench```的基准可见 [CPU Performance Ladder For Sysbench](https://sysbench.spiritlhl.net/) 天梯图,具体得分不分测试的sysbench的版本。 | ||||
|  | ||||
| ```GeekBench```的基准可见 [官方网站](https://browser.geekbench.com/processor-benchmarks/) 天梯图,具体得分每个```GeekBench```版本都不一样,注意使用时测试的```GeekBench```版本是什么。 | ||||
|  | ||||
| 多说一句,```GeekBench```测的很多内容,实际在服务器使用过程中根本用不到,测试仅供参考。当然```Sysbench```非常不全面,但它基于最基础的计算性能可以大致比较CPU的性能。 | ||||
| @@ -279,6 +281,8 @@ AMD's 7950x single-core full performance score is around 6500, AMD's 5950x singl | ||||
|  | ||||
| Sometimes multi-core scores are the same as single-core scores, proving that the vendor is limiting program concurrent use of CPU, a typical example being Tencent Cloud. | ||||
|  | ||||
| Benchmarks for ```Sysbench`` can be found in the [CPU Performance Ladder For Sysbench](https://sysbench.spiritlhl.net/) ladder chart, with specific scores regardless of the version of sysbench tested. | ||||
|  | ||||
| For `GeekBench` baselines, see the [official website](https://browser.geekbench.com/processor-benchmarks/) ladder chart. Specific scores differ for each `GeekBench` version, so note which `GeekBench` version is being used when testing. | ||||
|  | ||||
| As an additional note, many things tested by `GeekBench` are not actually used in server usage processes, so the test is for reference only. Of course, `Sysbench` is very incomplete, but it can roughly compare CPU performance based on the most basic computational performance. | ||||
| @@ -424,6 +428,8 @@ AMDの7950xシングルコアのフルパフォーマンススコアは約6500 | ||||
|  | ||||
| 時々、マルチコアスコアとシングルコアスコアが同じ場合があります。これは販売者がプログラムの並列CPU使用を制限していることを示しています。典型的な例はTencent Cloudです。 | ||||
|  | ||||
| Sysbenchのベンチマークは[CPU Performance Ladder For Sysbench](https://sysbench.spiritlhl.net/)のラダーチャートで見ることができる。 | ||||
|  | ||||
| ```GeekBench```の基準は[公式ウェブサイト](https://browser.geekbench.com/processor-benchmarks/)の階層チャートを参照してください。具体的なスコアは各```GeekBench```バージョンで異なるため、テスト時の```GeekBench```バージョンに注意してください。 | ||||
|  | ||||
| 補足ですが、```GeekBench```がテストする多くの内容は、サーバー使用過程で実際には必要ないことが多いです。テストは参考程度にしてください。もちろん```Sysbench```は非常に包括的ではありませんが、基本的な計算性能に基づいてCPUのパフォーマンスを大まかに比較できます。 | ||||
|   | ||||
| @@ -36,6 +36,6 @@ func DiskTest(language, testMethod, testPath string, isMultiCheck bool, autoChan | ||||
| 	if !strings.Contains(res, "\n") && res != "" { | ||||
| 		res += "\n" | ||||
| 	} | ||||
| 	fmt.Printf(res) | ||||
| 	fmt.Printf("%s", res) | ||||
| 	//fmt.Println("--------------------------------------------------") | ||||
| } | ||||
|   | ||||
| @@ -3,5 +3,5 @@ package disktest | ||||
| import "testing" | ||||
|  | ||||
| func TestDiskIoTest(t *testing.T) { | ||||
| 	DiskTest("zh", "sysbench", "", false) | ||||
| 	DiskTest("zh", "sysbench", "", false, false) | ||||
| } | ||||
|   | ||||
							
								
								
									
										8
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								go.mod
									
									
									
									
									
								
							| @@ -7,9 +7,9 @@ toolchain go1.24.2 | ||||
| require ( | ||||
| 	github.com/imroc/req/v3 v3.50.0 | ||||
| 	github.com/oneclickvirt/CommonMediaTests v0.0.4-20250329123841 | ||||
| 	github.com/oneclickvirt/UnlockTests v0.0.26-20250329125926 | ||||
| 	github.com/oneclickvirt/backtrace v0.0.5-20250517095024 | ||||
| 	github.com/oneclickvirt/basics v0.0.12-20250521031609 | ||||
| 	github.com/oneclickvirt/UnlockTests v0.0.27-20250628125053 | ||||
| 	github.com/oneclickvirt/backtrace v0.0.5-20250629024536 | ||||
| 	github.com/oneclickvirt/basics v0.0.13-20250629023612 | ||||
| 	github.com/oneclickvirt/cputest v0.0.10-20250404151448 | ||||
| 	github.com/oneclickvirt/defaultset v0.0.2-20240624082446 | ||||
| 	github.com/oneclickvirt/disktest v0.0.8-20250425015826 | ||||
| @@ -18,7 +18,7 @@ require ( | ||||
| 	github.com/oneclickvirt/nt3 v0.0.5-20250416131047 | ||||
| 	github.com/oneclickvirt/pingtest v0.0.7-20250413051539 | ||||
| 	github.com/oneclickvirt/portchecker v0.0.3-20250329125750 | ||||
| 	github.com/oneclickvirt/security v0.0.4-20250522031128 | ||||
| 	github.com/oneclickvirt/security v0.0.4-20250629033626 | ||||
| 	github.com/oneclickvirt/speedtest v0.0.9-20250521034111 | ||||
| ) | ||||
|  | ||||
|   | ||||
							
								
								
									
										16
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								go.sum
									
									
									
									
									
								
							| @@ -99,12 +99,12 @@ github.com/nxtrace/NTrace-core v1.4.0 h1:pDN2BqxIYjedDKCDDOFBcDNOBnavGcx+4wbiG65 | ||||
| github.com/nxtrace/NTrace-core v1.4.0/go.mod h1:0AWqbqiIJbpbFG6W48vtJ6pWM8PPF+lQ1fi2371y+zA= | ||||
| github.com/oneclickvirt/CommonMediaTests v0.0.4-20250329123841 h1:Zef93z9UiZQwRAKnnZYALmpBKvvuVaq34MEsuWwk6nc= | ||||
| github.com/oneclickvirt/CommonMediaTests v0.0.4-20250329123841/go.mod h1:DAmFPRjFV5p9fEzUUSml5jJGn2f1NZJQCzTxITHDjc4= | ||||
| github.com/oneclickvirt/UnlockTests v0.0.26-20250329125926 h1:H5//xwVjDR02bQ1hLa3G7LnwccsudPMjBVt7WCx2y/U= | ||||
| github.com/oneclickvirt/UnlockTests v0.0.26-20250329125926/go.mod h1:yXWIZB6iLS88pEd9m4QJi1GENn+7I91zA72y5ONz2Oc= | ||||
| github.com/oneclickvirt/backtrace v0.0.5-20250517095024 h1:j912aga/17znOqMB2VAxWOQYa4GL6YMFBhv+6c7jkvA= | ||||
| github.com/oneclickvirt/backtrace v0.0.5-20250517095024/go.mod h1:5AH00bo41hH3d2/JVuCTlBkZUs3AXX4nlKVXb6piZcI= | ||||
| github.com/oneclickvirt/basics v0.0.12-20250521031609 h1:3WxHe+jKrZHF81oa8Xk3IgHCRqTC5GDjv8alR0geamU= | ||||
| github.com/oneclickvirt/basics v0.0.12-20250521031609/go.mod h1:yN1IEOXN6v/GJqJSA70Pooo6nXBI/6rq72vTY72wJMQ= | ||||
| github.com/oneclickvirt/UnlockTests v0.0.27-20250628125053 h1:Ug8kySZR1weRUcsnGOv+f3HAl791AfkA7EWV3JmiMQA= | ||||
| github.com/oneclickvirt/UnlockTests v0.0.27-20250628125053/go.mod h1:yXWIZB6iLS88pEd9m4QJi1GENn+7I91zA72y5ONz2Oc= | ||||
| github.com/oneclickvirt/backtrace v0.0.5-20250629024536 h1:caHCa0DHmbYWBFN1bqKxpvPnN0wOxDEqJv1VDvDdLWs= | ||||
| github.com/oneclickvirt/backtrace v0.0.5-20250629024536/go.mod h1:5AH00bo41hH3d2/JVuCTlBkZUs3AXX4nlKVXb6piZcI= | ||||
| github.com/oneclickvirt/basics v0.0.13-20250629023612 h1:cQg+cGBt2NMRrjhJPH+CbevZrwtMU8pIZIY2Lp6zmt4= | ||||
| github.com/oneclickvirt/basics v0.0.13-20250629023612/go.mod h1:yN1IEOXN6v/GJqJSA70Pooo6nXBI/6rq72vTY72wJMQ= | ||||
| github.com/oneclickvirt/cputest v0.0.10-20250404151448 h1:ovGtCwFXG0qmpyNDRqcNDIiAmhrtemCjIUXTJ1fPH0o= | ||||
| github.com/oneclickvirt/cputest v0.0.10-20250404151448/go.mod h1:MmaHN9+XMntI3rLycwj8Ne31fG18IfNoa8N2utDK1CY= | ||||
| github.com/oneclickvirt/dd v0.0.1-20250406062523 h1:jegTww4fuoFEqwFozvGJEqUNI/5ew3QJ0XcKZZ/zuTs= | ||||
| @@ -125,8 +125,8 @@ github.com/oneclickvirt/pingtest v0.0.7-20250413051539 h1:mYOsEmMtwKr40hwM2NimVL | ||||
| github.com/oneclickvirt/pingtest v0.0.7-20250413051539/go.mod h1:d3Ntx5m9lMll3a/k3+2B+5emj//vgDh4/NHTxs2qQE8= | ||||
| github.com/oneclickvirt/portchecker v0.0.3-20250329125750 h1:TTNL0pnQlRsn046kW59I/9UWRpihttFHWnU7Ixycggk= | ||||
| github.com/oneclickvirt/portchecker v0.0.3-20250329125750/go.mod h1:HQxSTrqM8/QFqHMTBZ7S8H9eEO5FkUXU1eb7ZX5Mk+k= | ||||
| github.com/oneclickvirt/security v0.0.4-20250522031128 h1:k/zpiES/W0lW6Rumlmo4i7zp2ncimfeOUKadrylde8M= | ||||
| github.com/oneclickvirt/security v0.0.4-20250522031128/go.mod h1:hdCr9UFkJ0tQfFP4mIycZehF5v7VfzSQwNn2qkY0bGo= | ||||
| github.com/oneclickvirt/security v0.0.4-20250629033626 h1:DEchQ7WKKz4CzQpMlweoqA993BGncvmp1rL1ICNDJ2g= | ||||
| github.com/oneclickvirt/security v0.0.4-20250629033626/go.mod h1:/5eVnZLvP7RUjwhoI6d8iIMP7msbkHC5So3ZxM+A7Zg= | ||||
| github.com/oneclickvirt/speedtest v0.0.9-20250521034111 h1:yygDk+s5qFhPMDRzdMfyopm1xU512peNqY6WYyvYcfY= | ||||
| github.com/oneclickvirt/speedtest v0.0.9-20250521034111/go.mod h1:zd5ZgIGslmtQLQehEfRjyumlvgDHTpCSMchKfKXoASI= | ||||
| github.com/onsi/ginkgo/v2 v2.22.1 h1:QW7tbJAUDyVDVOM5dFa7qaybo+CRfR7bemlQUN6Z8aM= | ||||
|   | ||||
							
								
								
									
										8
									
								
								goecs.sh
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								goecs.sh
									
									
									
									
									
								
							| @@ -1,6 +1,6 @@ | ||||
| #!/bin/bash | ||||
| # From https://github.com/oneclickvirt/ecs | ||||
| # 2025.06.05 | ||||
| # 2025.06.29 | ||||
|  | ||||
| # curl -L https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && chmod +x goecs.sh | ||||
| # 或 | ||||
| @@ -143,7 +143,7 @@ goecs_check() { | ||||
|     os=$(uname -s 2>/dev/null || echo "Unknown") | ||||
|     arch=$(uname -m 2>/dev/null || echo "Unknown") | ||||
|     check_china | ||||
|     ECS_VERSION="" | ||||
|     ECS_VERSION="0.1.39" | ||||
|     for api in \ | ||||
|         "https://api.github.com/repos/oneclickvirt/ecs/releases/latest" \ | ||||
|         "https://githubapi.spiritlhl.workers.dev/repos/oneclickvirt/ecs/releases/latest" \ | ||||
| @@ -155,8 +155,8 @@ goecs_check() { | ||||
|         sleep 1 | ||||
|     done | ||||
|     if [ -z "$ECS_VERSION" ]; then | ||||
|         _yellow "Unable to get version info, using default version 0.1.33" | ||||
|         ECS_VERSION="0.1.33" | ||||
|         _yellow "Unable to get version info, using default version 0.1.39" | ||||
|         ECS_VERSION="0.1.39" | ||||
|     fi | ||||
|     version_output="" | ||||
|     for cmd_path in "goecs" "./goecs" "/usr/bin/goecs" "/usr/local/bin/goecs"; do | ||||
|   | ||||
| @@ -31,5 +31,5 @@ func MemoryTest(language, testMethod string) { | ||||
| 	if !strings.Contains(res, "\n") && res != "" { | ||||
| 		res += "\n" | ||||
| 	} | ||||
| 	fmt.Printf(res) | ||||
| 	fmt.Printf("%s", res) | ||||
| } | ||||
|   | ||||
| @@ -6,5 +6,5 @@ import ( | ||||
| ) | ||||
|  | ||||
| func Test(t *testing.T) { | ||||
| 	fmt.Printf(MediaTest("zh")) | ||||
| 	fmt.Printf("%s", MediaTest("zh")) | ||||
| } | ||||
|   | ||||
							
								
								
									
										174
									
								
								utils/utils.go
									
									
									
									
									
								
							
							
						
						
									
										174
									
								
								utils/utils.go
									
									
									
									
									
								
							| @@ -3,13 +3,11 @@ package utils | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"bytes" | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"github.com/imroc/req/v3" | ||||
| 	"github.com/oneclickvirt/UnlockTests/uts" | ||||
| 	"github.com/oneclickvirt/basics/system" | ||||
| 	. "github.com/oneclickvirt/defaultset" | ||||
| 	"github.com/oneclickvirt/security/network" | ||||
| 	"io" | ||||
| 	"net" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"regexp" | ||||
| @@ -17,6 +15,12 @@ import ( | ||||
| 	"sync" | ||||
| 	"time" | ||||
| 	"unicode/utf8" | ||||
|  | ||||
| 	"github.com/imroc/req/v3" | ||||
| 	"github.com/oneclickvirt/UnlockTests/uts" | ||||
| 	"github.com/oneclickvirt/basics/system" | ||||
| 	. "github.com/oneclickvirt/defaultset" | ||||
| 	"github.com/oneclickvirt/security/network" | ||||
| ) | ||||
|  | ||||
| // PrintCenteredTitle 根据指定的宽度打印居中标题 | ||||
| @@ -95,14 +99,14 @@ func CheckChina(enableLogger bool) bool { | ||||
| } | ||||
|  | ||||
| // BasicsAndSecurityCheck 执行安全检查 | ||||
| func BasicsAndSecurityCheck(language, nt3CheckType string, securtyCheckStatus bool) (string, string, string) { | ||||
| func BasicsAndSecurityCheck(language, nt3CheckType string, securityCheckStatus bool) (string, string, string) { | ||||
| 	var wgt sync.WaitGroup | ||||
| 	var ipInfo, securityInfo, systemInfo string | ||||
| 	var err error | ||||
| 	wgt.Add(1) | ||||
| 	go func() { | ||||
| 		defer wgt.Done() | ||||
| 		ipInfo, securityInfo, err = network.NetworkCheck("both", securtyCheckStatus, language) | ||||
| 		ipInfo, securityInfo, err = network.NetworkCheck("both", securityCheckStatus, language) | ||||
| 		if err != nil { | ||||
| 			fmt.Println(err.Error()) | ||||
| 		} | ||||
| @@ -330,3 +334,159 @@ func ProcessAndUpload(output string, filePath string, enableUplaod bool) (string | ||||
| 	} | ||||
| 	return "", "" | ||||
| } | ||||
|  | ||||
| // ============================= 前置联网能力检测 ============================= | ||||
|  | ||||
| var StackType string | ||||
|  | ||||
| type NetCheckResult struct { | ||||
| 	HasIPv4   bool | ||||
| 	HasIPv6   bool | ||||
| 	Connected bool | ||||
| 	StackType string // "IPv4", "IPv6", "DualStack", "None" | ||||
| } | ||||
|  | ||||
| func makeResolver(proto, dnsAddr string) *net.Resolver { | ||||
| 	return &net.Resolver{ | ||||
| 		PreferGo: true, | ||||
| 		Dial: func(ctx context.Context, network, address string) (net.Conn, error) { | ||||
| 			d := net.Dialer{ | ||||
| 				Timeout: 5 * time.Second, | ||||
| 			} | ||||
| 			return d.DialContext(ctx, proto, dnsAddr) | ||||
| 		}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func CheckPublicAccess(timeout time.Duration) NetCheckResult { | ||||
| 	if timeout < 2*time.Second { | ||||
| 		timeout = 2 * time.Second | ||||
| 	} | ||||
| 	var wg sync.WaitGroup | ||||
| 	resultChan := make(chan string, 8) | ||||
| 	ctx, cancel := context.WithTimeout(context.Background(), timeout) | ||||
| 	defer cancel() | ||||
| 	checks := []struct { | ||||
| 		Tag  string | ||||
| 		Addr string | ||||
| 		Kind string // udp4, udp6, http4, http6 | ||||
| 	}{ | ||||
| 		// UDP DNS | ||||
| 		{"IPv4", "223.5.5.5:53", "udp4"},              // 阿里 DNS | ||||
| 		{"IPv4", "8.8.8.8:53", "udp4"},                // Google DNS | ||||
| 		{"IPv6", "[2400:3200::1]:53", "udp6"},         // 阿里 IPv6 DNS | ||||
| 		{"IPv6", "[2001:4860:4860::8888]:53", "udp6"}, // Google IPv6 DNS | ||||
| 		// HTTP HEAD | ||||
| 		{"IPv4", "https://www.baidu.com", "http4"},     // 百度 | ||||
| 		{"IPv4", "https://1.1.1.1", "http4"},           // Cloudflare | ||||
| 		{"IPv6", "https://[2400:3200::1]", "http6"},    // 阿里 IPv6 | ||||
| 		{"IPv6", "https://[2606:4700::1111]", "http6"}, // Cloudflare IPv6 | ||||
| 	} | ||||
| 	for _, check := range checks { | ||||
| 		wg.Add(1) | ||||
| 		go func(tag, addr, kind string) { | ||||
| 			defer wg.Done() | ||||
| 			defer func() { | ||||
| 				if r := recover(); r != nil { | ||||
| 				} | ||||
| 			}() | ||||
| 			switch kind { | ||||
| 			case "udp4", "udp6": | ||||
| 				dialer := &net.Dialer{ | ||||
| 					Timeout: timeout / 4, | ||||
| 				} | ||||
| 				conn, err := dialer.DialContext(ctx, kind, addr) | ||||
| 				if err == nil && conn != nil { | ||||
| 					conn.Close() | ||||
| 					select { | ||||
| 					case resultChan <- tag: | ||||
| 					case <-ctx.Done(): | ||||
| 						return | ||||
| 					} | ||||
| 				} | ||||
| 			case "http4", "http6": | ||||
| 				var resolver *net.Resolver | ||||
| 				if kind == "http4" { | ||||
| 					resolver = makeResolver("udp4", "223.5.5.5:53") | ||||
| 				} else { | ||||
| 					resolver = makeResolver("udp6", "[2400:3200::1]:53") | ||||
| 				} | ||||
| 				dialer := &net.Dialer{ | ||||
| 					Timeout:  timeout / 4, | ||||
| 					Resolver: resolver, | ||||
| 				} | ||||
| 				transport := &http.Transport{ | ||||
| 					DialContext:           dialer.DialContext, | ||||
| 					MaxIdleConns:          1, | ||||
| 					MaxIdleConnsPerHost:   1, | ||||
| 					IdleConnTimeout:       time.Second, | ||||
| 					TLSHandshakeTimeout:   timeout / 4, | ||||
| 					ResponseHeaderTimeout: timeout / 4, | ||||
| 					DisableKeepAlives:     true, | ||||
| 				} | ||||
| 				client := &http.Client{ | ||||
| 					Timeout:   timeout / 4, | ||||
| 					Transport: transport, | ||||
| 					CheckRedirect: func(req *http.Request, via []*http.Request) error { | ||||
| 						return http.ErrUseLastResponse | ||||
| 					}, | ||||
| 				} | ||||
| 				req, err := http.NewRequestWithContext(ctx, "HEAD", addr, nil) | ||||
| 				if err != nil { | ||||
| 					return | ||||
| 				} | ||||
| 				resp, err := client.Do(req) | ||||
| 				if err == nil && resp != nil { | ||||
| 					if resp.Body != nil { | ||||
| 						resp.Body.Close() | ||||
| 					} | ||||
| 					if resp.StatusCode < 500 { | ||||
| 						select { | ||||
| 						case resultChan <- tag: | ||||
| 						case <-ctx.Done(): | ||||
| 							return | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		}(check.Tag, check.Addr, check.Kind) | ||||
| 	} | ||||
| 	go func() { | ||||
| 		wg.Wait() | ||||
| 		close(resultChan) | ||||
| 	}() | ||||
| 	hasV4 := false | ||||
| 	hasV6 := false | ||||
| 	for { | ||||
| 		select { | ||||
| 		case res, ok := <-resultChan: | ||||
| 			if !ok { | ||||
| 				goto result | ||||
| 			} | ||||
| 			if res == "IPv4" { | ||||
| 				hasV4 = true | ||||
| 			} | ||||
| 			if res == "IPv6" { | ||||
| 				hasV6 = true | ||||
| 			} | ||||
| 		case <-ctx.Done(): | ||||
| 			goto result | ||||
| 		} | ||||
| 	} | ||||
| result: | ||||
| 	stack := "None" | ||||
| 	if hasV4 && hasV6 { | ||||
| 		stack = "DualStack" | ||||
| 	} else if hasV4 { | ||||
| 		stack = "IPv4" | ||||
| 	} else if hasV6 { | ||||
| 		stack = "IPv6" | ||||
| 	} | ||||
| 	StackType = stack | ||||
| 	return NetCheckResult{ | ||||
| 		HasIPv4:   hasV4, | ||||
| 		HasIPv6:   hasV6, | ||||
| 		Connected: hasV4 || hasV6, | ||||
| 		StackType: stack, | ||||
| 	} | ||||
| } | ||||
|   | ||||
							
								
								
									
										17
									
								
								utils/utils_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								utils/utils_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| package utils | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"testing" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| func TestCheckPublicAccess(t *testing.T) { | ||||
| 	timeout := 3 * time.Second | ||||
| 	result := CheckPublicAccess(timeout) | ||||
| 	if result.Connected { | ||||
| 		fmt.Printf("✅ 本机有公网连接,类型: %s\n", result.StackType) | ||||
| 	} else { | ||||
| 		fmt.Println("❌ 本机未检测到公网连接") | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user