Compare commits

...

101 Commits

Author SHA1 Message Date
tsosunchia
29ce61b24b 更新readme 2023-10-14 09:21:05 +08:00
tsosunchia
701abc3447 增加file参数支持文件读取列表进行路由测试 2023-10-14 09:08:29 +08:00
tsosunchia
f08778c862 修正部分typo 2023-10-13 18:34:14 +08:00
tsosunchia
8697325193 Merge pull request #17 from 1-1-2/softfloat
add mips softfloat & mipsle softfloat
2023-10-13 18:03:21 +08:00
1-1-2
32b0f15e78 add mips softfloat & mipsle softfloat 2023-10-13 16:46:20 +08:00
tsosunchia
90e349eeed Merge pull request #181 from nxtrace/main
更新readme
2023-10-13 10:49:48 +08:00
tsosunchia
f275edba3a 更新readme 2023-10-13 10:49:20 +08:00
tsosunchia
2974002c02 Merge pull request #178 from nxtrace/main
chore: 同步V1版本
2023-10-12 19:52:57 +08:00
tsosunchia
9b2fc9b570 Merge pull request #16 from nxtrace/dependabot/go_modules/golang.org/x/net-0.17.0
chore(deps): bump golang.org/x/net from 0.16.0 to 0.17.0
2023-10-12 17:48:58 +08:00
tsosunchia
960ab9687c 修复无v6网络下的连接问题 2023-10-12 17:47:31 +08:00
dependabot[bot]
07623ce4fd chore(deps): bump golang.org/x/net from 0.16.0 to 0.17.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.16.0 to 0.17.0.
- [Commits](https://github.com/golang/net/compare/v0.16.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-11 23:17:18 +00:00
tsosunchia
3164acfccf Merge pull request #173 from nxtrace/main
fix bug: ipv6局域网地址错误显示为INVALID
2023-10-11 10:57:51 +08:00
tsosunchia
8b30ef39dd fix bug: ipv6局域网地址错误显示为INVALID 2023-10-11 10:22:14 +08:00
tsosunchia
239b1c2f8d Merge pull request #172 from nxtrace/main
update readme
2023-10-09 08:16:24 +08:00
tsosunchia
ed3c158e87 更新下载方式 2023-10-09 08:14:04 +08:00
tsosunchia
02348f08c0 skywolf image update 2023-10-09 08:14:04 +08:00
tsosunchia
9c7402accb Merge pull request #171 from nxtrace/main
仓库用途变更
2023-10-08 17:21:44 +08:00
tsosunchia
a6848f8f23 仓库用途变更
要提交的变更:
	修改:     .github/workflows/build.yml
	修改:     .github/workflows/publishNewFormula.yml
	修改:     README.md
	修改:     README_zh_CN.md
	修改:     fast_trace/fast_trace_test.go
	修改:     go.mod
	修改:     go.sum
	修改:     pow/pow.go
	修改:     printer/basic.go
	修改:     util/latency.go
	修改:     util/latency_test.go
	修改:     util/util.go
	修改:     wshandle/client.go
2023-10-08 17:15:29 +08:00
tsosunchia
29b7c668a4 rename nt_install_v1.sh 2023-10-08 17:13:57 +08:00
tsosunchia
86eacc006e 更新readme 2023-10-08 17:11:35 +08:00
tsosunchia
81d6df8b82 更新readme 2023-10-08 17:07:24 +08:00
tsosunchia
dbe42d669c 更新依赖,优化显示 2023-10-08 16:33:25 +08:00
tsosunchia
a7089e8d54 更换homebrew地址 2023-10-06 21:35:17 +08:00
tsosunchia
bcda750a66 更新homebrew仓库地址地址 2023-10-06 21:30:35 +08:00
tsosunchia
1580c6111f add mpls func 2023-10-06 21:03:38 +08:00
tsosunchia
a3ef1b2574 update credit 2023-10-06 20:55:44 +08:00
tsosunchia
ba27ff967b chore: resolve incorrect conversion between integer types
https://github.com/nxtrace/NTrace-V1/security/code-scanning/1
 要提交的变更:
	修改:     trace/icmp_ipv4.go
2023-10-06 20:30:25 +08:00
tsosunchia
b326d7bed6 更新readme 2023-10-06 06:19:24 +08:00
tsosunchia
b733ef2d82 增加对多MPLS情景的支持,支持通过ENV或参数禁用MPLS功能
要提交的变更:
	修改:     cmd/cmd.go
	修改:     printer/basic.go
	修改:     printer/printer.go
	修改:     printer/realtime_printer.go
	修改:     trace/icmp_ipv4.go
	修改:     trace/icmp_ipv6.go
	修改:     trace/trace.go
	修改:     util/util.go
2023-10-06 06:02:09 +08:00
tsosunchia
2113264336 ipv6 mpls support 2023-10-05 07:25:05 +08:00
tsosunchia
ba7d6ea87b 重构mpls icmpv4 代码 2023-10-05 06:47:28 +08:00
tsosunchia
db1e9e2b0c v4 mpls实装显示 2023-10-05 06:42:04 +08:00
tsosunchia
13aaa54067 可显示MPLS LABEL 2023-10-05 05:12:01 +08:00
tsosunchia
db9b3fed9a 已经可以检测到MPLS 2023-10-05 04:30:09 +08:00
tsosunchia
7b145f4e64 增加ip2region下载db错误处理 2023-10-05 00:55:44 +08:00
tsosunchia
d444ff3c62 fix bug:IPv4被错误识别为LAN地址 2023-10-05 00:45:06 +08:00
tsosunchia
f1ceaf7f86 rename mod 2023-10-05 00:18:18 +08:00
tsosunchia
d6536f7c69 chore:更新依赖 2023-10-04 23:58:44 +08:00
tsosunchia
ae2e6b3631 修改fasttrace默认行为 2023-10-04 23:42:35 +08:00
tsosunchia
f63ef9552e 修正过滤器 2023-10-03 01:57:11 +08:00
tsosunchia
ce1bae2125 Merge pull request #13 from nxtrace/dependabot/go_modules/github.com/tidwall/gjson-1.17.0
chore(deps): bump github.com/tidwall/gjson from 1.16.0 to 1.17.0
2023-09-25 22:34:52 +08:00
dependabot[bot]
9d3878efbe chore(deps): bump github.com/tidwall/gjson from 1.16.0 to 1.17.0
Bumps [github.com/tidwall/gjson](https://github.com/tidwall/gjson) from 1.16.0 to 1.17.0.
- [Commits](https://github.com/tidwall/gjson/compare/v1.16.0...v1.17.0)

---
updated-dependencies:
- dependency-name: github.com/tidwall/gjson
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-25 14:32:39 +00:00
tsosunchia
c940b9f19f 更新go及依赖 2023-09-13 00:03:35 +08:00
tsosunchia
2d6ae4ff4c Merge pull request #10 from nxtrace/dependabot/go_modules/golang.org/x/net-0.15.0
chore(deps): bump golang.org/x/net from 0.14.0 to 0.15.0
2023-09-11 23:23:51 +08:00
dependabot[bot]
7977383fec chore(deps): bump golang.org/x/net from 0.14.0 to 0.15.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.14.0 to 0.15.0.
- [Commits](https://github.com/golang/net/compare/v0.14.0...v0.15.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-11 14:26:49 +00:00
tsosunchia
ae16731bbe update readme 2023-09-09 17:21:50 +08:00
tsosunchia
e0ea009b2c update readme 2023-09-09 16:55:59 +08:00
sjlleo
c532dfd05c improve: plugin hook for TTLComplete 2023-09-07 22:20:55 +08:00
tsosunchia
b967ee411d tracemap支持IP-API.COM做为API,修正第三方API部分地区显示问题 2023-09-07 16:35:51 +08:00
tsosunchia
46ce56f3a7 使用ipinfo api时支持显示tracemap,正确识别ANYCAST坐标 2023-09-07 13:27:19 +08:00
sjlleo
bb522ed859 refactor && feat: add plugin system && cobra 2023-09-05 22:18:28 +08:00
tsosunchia
cdfe926c37 更改pow失败时的错误提示 2023-09-05 22:01:45 +08:00
tsosunchia
aa7cea4cf8 dod也纳入考虑 2023-09-05 21:50:23 +08:00
tsosunchia
549dc549dd 网络故障时,不再显示为局域网
@XQZR 你要的我修好了🤗(希望)
2023-09-05 21:16:07 +08:00
tsosunchia
76fa8f2019 Merge pull request #9 from nxtrace/dependabot/github_actions/actions/checkout-4
chore(deps): bump actions/checkout from 3 to 4
2023-09-04 22:57:17 +08:00
dependabot[bot]
9e17f4a24f chore(deps): bump actions/checkout from 3 to 4
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-04 14:48:59 +00:00
tsosunchia
b06487e293 Update README_zh_CN.md 2023-09-04 22:10:55 +08:00
tsosunchia
a0ab83c8ed 增加指定第三方POW服务器的参数及环境变量 2023-09-02 19:45:07 +08:00
sjlleo
9e5cd736c8 doc: supplement NextTrace v1/v2 Branch content 2023-09-02 19:27:51 +08:00
tsosunchia
b11d2334c2 Update README_zh_CN.md 2023-09-01 10:45:46 +08:00
tsosunchia
84a03e8a10 Update README.md 2023-09-01 10:45:26 +08:00
tsosunchia
761d506613 Update README 2023-09-01 08:32:21 +08:00
tsosunchia
c3ab3e6c1c fix:当接口多IP时,指定接口路由导致不能正常运行的问题 2023-08-31 20:02:54 +08:00
tsosunchia
96671d263c 修复了macos下ipv6不能指定dev的问题 2023-08-31 13:19:21 +08:00
tsosunchia
9228cdf307 Update README_zh_CN.md 2023-08-31 09:01:16 +08:00
tsosunchia
12565941ab Update README.md 2023-08-31 09:00:17 +08:00
sjlleo
e33548d2ce Update README 2023-08-31 00:12:39 +08:00
tsosunchia
5d766de52f Update readme 2023-08-31 00:11:49 +08:00
tsosunchia
ce46abd232 更新golang1.21 2023-08-30 20:47:32 +08:00
tsosunchia
6179f1b8f0 Update README 2023-08-30 20:47:32 +08:00
tsosunchia
3c12d99168 更新所有依赖 2023-08-16 23:11:52 +08:00
tsosunchia
f3f99ac0aa fix bugs:--source and --dev doesn't work on macOS
https://github.com/nxtrace/Ntrace-core/issues/147
2023-08-16 22:44:18 +08:00
tsosunchia
cb7bc7450f Update basic.go 2023-08-15 17:26:13 +08:00
tsosunchia
74f46f5d24 fix bugs:proxy settings
https://github.com/nxtrace/Ntrace-V1/pull/2#issuecomment-1610979252
2023-06-28 23:41:58 +08:00
tsosunchia
2bc386355c fix bugs:proxy settings
https://github.com/nxtrace/Ntrace-V1/pull/2#issuecomment-1610979252
2023-06-28 23:06:48 +08:00
tsosunchia
1266f62aba Update README 2023-06-26 14:52:44 +08:00
Leo
8e837072c6 doc: README_zh_CN 2023-06-26 14:52:41 +08:00
sjlleo
cf0639111d fix: install fail 2023-06-26 14:52:37 +08:00
sjlleo
56cd0022f7 remove: channel link is illegal and has been removed. 2023-06-26 14:52:33 +08:00
tsosunchia
1407c499b9 Update README 2023-06-26 14:52:27 +08:00
sjlleo
f25662d481 doc: future change 2023-06-26 14:52:22 +08:00
tsosunchia
4f94f01e87 Merge pull request #128 from fakeboboliu/fix1
improve: rootless trace on macOS
2023-06-26 14:52:12 +08:00
Leo
1460ad67c0 refactor: nexttrace core 2023-06-26 14:52:05 +08:00
Leo
d6dcfc8dc5 feat: try add UDP IPv6 Support 2023-06-26 14:51:59 +08:00
Leo
190b3ab94e chore: add begin hop / srcaddr listen 2023-06-26 14:51:54 +08:00
Leo
87fa850d2d chore: sync to the latest repository name 2023-06-26 14:51:48 +08:00
Leo
c71a26d018 fix: name change caused installation failure 2023-06-26 14:51:36 +08:00
Leo
79c39b655a clean mod && delete useless files 2023-06-26 14:51:19 +08:00
tsosunchia
580612ce08 refactor: preparatory work 2023-06-26 14:49:05 +08:00
tsosunchia
141653a3e9 增加版本说明 2023-06-17 20:38:36 +08:00
tsosunchia
f59d7ff2f5 chore:更改相关url 2023-06-17 20:11:10 +08:00
tsosunchia
87f153cdf1 Update README.md 2023-06-17 03:23:14 +08:00
tsosunchia
ebe2a0f8e9 update readme 2023-06-15 12:42:28 +08:00
tsosunchia
ca2a7a8dc8 Update build/test action & readme
update readme

Update test.yml
2023-06-15 11:43:17 +08:00
tsosunchia
b68b768a65 Merge pull request #138 from tsosunchia/main
支持通过设置SOCKS5/HTTP代理访问我们的API
2023-06-14 23:03:24 +08:00
tsosunchia
efbede8ca1 Update build.yml
actions运作发版时,先存储为draft
2023-06-14 22:16:38 +08:00
tsosunchia
b1edef305f Merge pull request #2 from tsosunchia/proxyenv
增加支持SOCKS5/HTTP代理,通过环境变量NEXTTRACE_PROXY配置.
2023-06-07 03:21:12 +08:00
tsosunchia
54242cfa8b 增加支持SOCKS5/HTTP代理,通过环境变量NEXTTRACE_PROXY配置.
如export NEXTTRACE_PROXY=socks5://127.0.0.1:10808
2023-06-07 03:15:29 +08:00
tsosunchia
2d4de9e4c1 Update .cross_compile.sh 2023-06-04 20:34:17 +08:00
tsosunchia
d75a384d70 Update nt_install.sh 2023-06-04 13:12:40 +08:00
tsosunchia
f6fbf3803f UPDATE README 2023-06-04 12:38:24 +08:00
51 changed files with 1203 additions and 392 deletions

View File

@@ -26,15 +26,15 @@ for pl in ${PLATFORMS}; do
echo "build => ${TARGET}"
if [ "${DEBUG_MODE}" == "debug" ]; then
go build -trimpath -gcflags "all=-N -l" -o ${TARGET} \
-ldflags "-X 'github.com/xgadget-lab/nexttrace/config.Version=${BUILD_VERSION}' \
-X 'github.com/xgadget-lab/nexttrace/config.BuildDate=${BUILD_DATE}' \
-X 'github.com/xgadget-lab/nexttrace/config.CommitID=${COMMIT_SHA1}'\
-ldflags "-X 'github.com/nxtrace/NTrace-core/config.Version=${BUILD_VERSION}' \
-X 'github.com/nxtrace/NTrace-core/config.BuildDate=${BUILD_DATE}' \
-X 'github.com/nxtrace/NTrace-core/config.CommitID=${COMMIT_SHA1}'\
-w -s"
else
go build -trimpath -o ${TARGET} \
-ldflags "-X 'github.com/xgadget-lab/nexttrace/config.Version=${BUILD_VERSION}' \
-X 'github.com/xgadget-lab/nexttrace/config.BuildDate=${BUILD_DATE}' \
-X 'github.com/xgadget-lab/nexttrace/config.CommitID=${COMMIT_SHA1}'\
-ldflags "-X 'github.com/nxtrace/NTrace-core/config.Version=${BUILD_VERSION}' \
-X 'github.com/nxtrace/NTrace-core/config.BuildDate=${BUILD_DATE}' \
-X 'github.com/nxtrace/NTrace-core/config.CommitID=${COMMIT_SHA1}'\
-w -s"
fi
done
@@ -46,15 +46,15 @@ done
echo "build => ${TARGET}"
if [ "${DEBUG_MODE}" == "debug" ]; then
go build -trimpath -gcflags "all=-N -l" -o ${TARGET} \
-ldflags "-X 'github.com/xgadget-lab/nexttrace/printer.version=${BUILD_VERSION}' \
-X 'github.com/xgadget-lab/nexttrace/printer.buildDate=${BUILD_DATE}' \
-X 'github.com/xgadget-lab/nexttrace/printer.commitID=${COMMIT_SHA1}'\
-ldflags "-X 'github.com/nxtrace/NTrace-core/config.Version=${BUILD_VERSION}' \
-X 'github.com/nxtrace/NTrace-core/config.BuildDate=${BUILD_DATE}' \
-X 'github.com/nxtrace/NTrace-core/config.CommitID=${COMMIT_SHA1}'\
-w -s"
else
go build -trimpath -o ${TARGET} \
-ldflags "-X 'github.com/xgadget-lab/nexttrace/printer.version=${BUILD_VERSION}' \
-X 'github.com/xgadget-lab/nexttrace/printer.buildDate=${BUILD_DATE}' \
-X 'github.com/xgadget-lab/nexttrace/printer.commitID=${COMMIT_SHA1}'\
-ldflags "-X 'github.com/nxtrace/NTrace-core/config.Version=${BUILD_VERSION}' \
-X 'github.com/nxtrace/NTrace-core/config.BuildDate=${BUILD_DATE}' \
-X 'github.com/nxtrace/NTrace-core/config.CommitID=${COMMIT_SHA1}'\
-w -s"
fi

View File

@@ -15,7 +15,7 @@ copyright: [v2fly](https://github.com/v2fly)
<!--
除非特殊情况,请完整填写所有问题。不按模板发的 issue 将直接被关闭。
如果你遇到的问题不是 nexttrace 的 bug比如你不清楚如何配置请在 https://github.com/xgadget-lab/nexttrace/discussions 进行讨论。
如果你遇到的问题不是 nexttrace 的 bug比如你不清楚如何配置请在 https://github.com/nxtrace/NTrace-core/discussions 进行讨论。
-->
## 你正在使用哪个版本的 nexttrace

View File

@@ -75,6 +75,12 @@ jobs:
goarch: mipsle
- goos: linux
goarch: mips
- goos: linux
goarch: mipsle
gomips: softfloat
- goos: linux
goarch: mips
gomips: softfloat
# END MIPS
# BEGIN PPC
- goos: linux
@@ -104,10 +110,11 @@ jobs:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
GOARM: ${{ matrix.goarm }}
GOMIPS: ${{ matrix.gomips }}
CGO_ENABLED: 0
steps:
- name: Checkout codebase
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Show workflow information
run: |
if [ ! -z $GOARM ]; then
@@ -117,7 +124,10 @@ jobs:
if [ "$GOOS" == "windows" ]; then
export _NAME="$_NAME.exe"
fi
echo "GOOS: $GOOS, GOARCH: $GOARCH, GOARM: $GOARM, RELEASE_NAME: $_NAME"
if [ "$GOMIPS" == "softfloat" ]; then
export _NAME="${_NAME}_softfolat"
fi
echo "GOOS: $GOOS, GOARCH: $GOARCH, GOARM: $GOARM, GOMIPS: $GOMIPS, RELEASE_NAME: $_NAME"
echo "ASSET_NAME=$_NAME" >> $GITHUB_ENV
echo "BUILD_VERSION=$(git describe --tags --always)" >> $GITHUB_ENV
echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV
@@ -125,15 +135,15 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.20'
go-version: '1.21'
- name: Get project dependencies
run: go mod download
- name: Build
run: |
go build -trimpath -o dist/${ASSET_NAME} \
-ldflags "-X 'github.com/xgadget-lab/nexttrace/config.Version=${BUILD_VERSION}' \
-X 'github.com/xgadget-lab/nexttrace/config.BuildDate=${BUILD_DATE}' \
-X 'github.com/xgadget-lab/nexttrace/config.CommitID=${COMMIT_SHA1}'\
-ldflags "-X 'github.com/nxtrace/NTrace-core/config.Version=${BUILD_VERSION}' \
-X 'github.com/nxtrace/NTrace-core/config.BuildDate=${BUILD_DATE}' \
-X 'github.com/nxtrace/NTrace-core/config.CommitID=${COMMIT_SHA1}'\
-w -s"
- name: Upload files to Artifacts
uses: actions/upload-artifact@v3
@@ -145,7 +155,7 @@ jobs:
if: startsWith(github.ref, 'refs/tags/v')
uses: softprops/action-gh-release@v1
with: # 将下述可执行文件 release 上去
draft: false # Release草稿
draft: true # Release草稿
files: |
dist/*
env:
@@ -166,7 +176,7 @@ jobs:
git config --global user.name "${{ secrets.git_name }}"
- name: Clone repo
run: |
git clone https://github.com/xgadget-lab/homebrew-nexttrace.git
git clone https://github.com/nxtrace/homebrew-nexttrace.git
- name: Exec scipt
run: |
cd homebrew-nexttrace
@@ -183,7 +193,7 @@ jobs:
run: |
cd homebrew-nexttrace
git commit -am 'Publish a new version with Formula' || true
git remote set-url origin https://${{ secrets.gt_token }}@github.com/xgadget-lab/homebrew-nexttrace.git
git remote set-url origin https://${{ secrets.gt_token }}@github.com/nxtrace/homebrew-nexttrace.git
git push
# env:
# SSH_AUTH_SOCK: /tmp/ssh_agent.sock

View File

@@ -21,7 +21,7 @@ jobs:
git config --global user.name "${{ secrets.git_name }}"
- name: Clone repo
run: |
git clone https://github.com/xgadget-lab/homebrew-nexttrace.git
git clone https://github.com/nxtrace/homebrew-nexttrace.git
- name: Exec scipt
run: |
cd homebrew-nexttrace
@@ -38,7 +38,7 @@ jobs:
run: |
cd homebrew-nexttrace
git commit -am 'Publish a new version with Formula' || true
git remote set-url origin https://${{ secrets.gt_token }}@github.com/xgadget-lab/homebrew-nexttrace.git
git remote set-url origin https://${{ secrets.gt_token }}@github.com/nxtrace/homebrew-nexttrace.git
git push
# env:
# SSH_AUTH_SOCK: /tmp/ssh_agent.sock

View File

@@ -31,13 +31,13 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.20'
go-version: '1.21'
check-latest: true
- name: Checkout codebase
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Test with unix
if: ${{ matrix.os != 'windows-latest' }}
run: sudo go test -v -coverprofile='coverage.out' -covermode=count ./...
- name: Test with windows
if: ${{ matrix.os == 'windows-latest' }}
run: go test -v -coverprofile='coverage.out' -covermode=count ./...
run: go test -v -coverprofile='coverage.out' -covermode=count ./...

123
README.md
View File

@@ -4,47 +4,82 @@
</div>
## NextTrace
<h1 align="center">
<br>NextTrace<br>
</h1>
An open source visual routing tool that pursues light weight, developed using Golang.
<h4 align="center">An open source visual routing tool that pursues light weight, developed using Golang.</h4>
NextTrace is part of the [OwO Network](https://github.com/OwO-Network) project. The project is a joint initiative of Leo and Vincent.
<p align="center">
<a href="https://github.com/nxtrace/Ntrace-V1/actions">
<img src="https://img.shields.io/github/actions/workflow/status/nxtrace/Ntrace-V1/build.yml?branch=main&style=flat-square" alt="Github Actions">
</a>
<a href="https://goreportcard.com/report/github.com/nxtrace/Ntrace-V1">
<img src="https://goreportcard.com/badge/github.com/nxtrace/Ntrace-V1?style=flat-square">
</a>
<a href="https://github.com/nxtrace/Ntrace-V1/releases">
<img src="https://img.shields.io/github/release/nxtrace/Ntrace-V1/all.svg?style=flat-square">
</a>
<a href="https://telegram.dog/sjprojects">
<img src="https://img.shields.io/endpoint?color=neon&style=flat-square&url=https%3A%2F%2Ftg.sumanjay.workers.dev%2Fnexttrace">
</a>
</p>
If you like this project, [Donate us](https://afdian.net/a/sjlleo/plan) to help us to provide long-lasting API cost expenses.
## IAAS Sponsor
<div style="text-align: center;">
<a href="https://dmit.io">
<img src="https://www.dmit.io/templates/dmit_theme_2020/dmit/assets/images/dmit_logo_with_text_blue.svg" width="170.7" height="62.9">
</a>
&nbsp;&nbsp;&nbsp;&nbsp;
<a href="https://misaka.io" >
<img src="https://www.jsdelivr.com/assets/8997e39e1f9d776502ab4d7cdff9d1608aa67aaf/img/globalping/sponsors/misaka.svg" width="170.7" height="62.9">
</a>
&nbsp;&nbsp;&nbsp;&nbsp;
<a href="https://skywolf.cloud" >
<img src="https://hk.skywolf.cloud/assets/img/skywolf.svg" width="170.7" height="62.9">
</a>
</div>
We are extremely grateful to [DMIT](https://dmit.io) and [Misaka](https://misaka.io) and [Skywolf](https://skywolf.cloud) for providing the network infrastructure that powers this project.
## How To Use
Document Language: English | [简体中文](README_zh_CN.md)
⚠️ Please note: We welcome PR submissions from the community, but please submit your PRs to the [NTrace-V1](https://github.com/nxtrace/NTrace-V1) repository instead of [NTrace-core](https://github.com/nxtrace/NTrace-core) repository.<br>
Regarding the NTrace-V1 and NTrace-core repositories:<br>
Both will largely remain consistent with each other. All development work is done within the NTrace-V1 repository. The NTrace-V1 repository releases new versions first. After running stably for an undetermined period, we will synchronize that version to NTrace-core. This means that the NTrace-V1 repository serves as a "beta" or "testing" version.<br>
Please note, there are exceptions to this synchronization. If a version of NTrace-V1 encounters a serious bug, NTrace-core will skip that flawed version and synchronize directly to the next version that resolves the issue.
### Automated Install
* Linux
* One-click installation script
* Download from GitHub
```shell
bash -c "$(curl -Ls https://github.com/sjlleo/nexttrace/raw/main/nt_install.sh)"
```
* GHPROXY mirror (For use in Mainland China)
```shell
bash -c "$(curl -Ls https://ghproxy.com/https://github.com/sjlleo/nexttrace/raw/main/nt_install.sh)"
```
```shell
bash -c "$(curl http://nexttrace-io-leomoe-api-a0.shop/nt_install_v1.sh)"
```
* Arch Linux AUR installation command
* Build from source
```shell
yay -S nexttrace
```
* Directly download bin package (only supports amd64)
```shell
yay -S nexttrace-bin
```
* The two types of AUR builds are maintained by huyz and ouuan, respectively
* The AUR builds are maintained by ouuan
* Linuxbrew's installation command
Same as the macOS Homebrew's installation method (homebrew-core version only supports amd64)
* Deepin installation command
```shell
apt install nexttrace
```
* Termux installation command
```shell
pkg install nexttrace-enhanced
```
* macOS
* macOS Homebrew's installation command
@@ -56,7 +91,7 @@ Document Language: English | [简体中文](README_zh_CN.md)
* This repository's ACTIONS automatically built version (updates faster)
```shell
brew tap xgadget-lab/nexttrace && brew install nexttrace
brew tap nxtrace/nexttrace && brew install nxtrace/nexttrace/nexttrace
```
* The homebrew-core build is maintained by chenrui333, please note that this version's updates may lag behind the repository Action automatically version
@@ -75,7 +110,7 @@ Document Language: English | [简体中文](README_zh_CN.md)
### Manual Install
* Download the precompiled executable
For users not covered by the above methods, please go directly to [Release](https://github.com/sjlleo/nexttrace/releases/latest) to download the compiled binary executable.
For users not covered by the above methods, please go directly to [Release](https://github.com/nxtrace/Ntrace-V1/releases/latest) to download the compiled binary executable.
* `Release` provides compiled binary executables for many systems and different architectures. If none are available, you can compile it yourself.
* Some essential dependencies of this project are not fully implemented on `Windows` by `Golang`, so currently, `NextTrace` is in an experimental support phase on the `Windows` platform.
@@ -85,7 +120,7 @@ Document Language: English | [简体中文](README_zh_CN.md)
After installing Go >= 1.20 yourself, you can use the following command to install
```shell
go install github.com/xgadget-lab/nexttrace@latest
go install github.com/nxtrace/Ntrace-V1@latest
```
After installation, the executable is in the `$GOPATH/bin` directory. If you have not set `GOPATH`, it is in the `$HOME/go/bin` directory.
@@ -117,6 +152,10 @@ nexttrace 2606:4700:4700::1111
# Disable Path Visualization With the -M parameter
nexttrace koreacentral.blob.core.windows.net
# MapTrace URL: https://api.leo.moe/tracemap/html/c14e439e-3250-5310-8965-42a1e3545266.html
# Disable MPLS display using the --disable-mpls / -e parameter or the NEXTTRACE_DISABLEMPLS environment variable
nexttrace --disable-mpls example.com
export NEXTTRACE_DISABLEMPLS=1
```
PS: The routing visualization drawing module was written by [@tsosunchia](https://github.com/tsosunchia), and the specific code can be viewed at [tsosunchia/traceMap](https://github.com/tsosunchia/traceMap).
@@ -133,6 +172,17 @@ nexttrace --fast-trace
# You can also use TCP SYN for testing
nexttrace --fast-trace --tcp
# You can also quickly test through a customized IP/DOMAIN list file
nexttrace --file /path/to/your/iplist.txt
# CUSTOMIZED IP DOMAIN LIST FILE FORMAT
## One IP/DOMAIN per line + space + description information (optional)
## forExample:
## 106.37.67.1 BEIJING-TELECOM
## 240e:928:101:31a::1 BEIJING-TELECOM
## bj.10086.cn BEIJING-MOBILE
## 2409:8080:0:1::1
## 223.5.5.5
```
`NextTrace` already supports route tracing for specified Network Devices
@@ -237,7 +287,7 @@ NextTrace `LeoMoeAPI` now utilizes the Proof of Work (POW) mechanism to prevent
- [GitHub - tsosunchia/powclient: Proof of Work CLIENT for NextTrace](https://github.com/tsosunchia/powclient)
- [GitHub - tsosunchia/powserver: Proof of Work SERVER for NextTrace](https://github.com/tsosunchia/powserver)
All NextTrace IP geolocation `API DEMO` can refer to [here](https://github.com/xgadget-lab/nexttrace/blob/main/ipgeo/)
All NextTrace IP geolocation `API DEMO` can refer to [here](https://github.com/nxtrace/NTrace-core/blob/main/ipgeo/)
### For full usage list, please refer to the usage menu
@@ -286,6 +336,9 @@ Arguments:
IPInfo, IPInsight, IP-API.com, Ip2region,
IPInfoLocal, CHUNZHEN, disable-geoip].
Default: LeoMoeAPI
--pow-provider Choose PoW Provider [api.leo.moe, sakura]
For China mainland users, please use
sakura. Default: api.leo.moe
-n --no-rdns Do not resolve IP addresses to their
domain names
-a --always-rdns Always resolve IP addresses to their
@@ -304,6 +357,7 @@ Arguments:
-f --first Start from the first_ttl hop (instead from
1). Default: 1
-M --map Disable Print Trace Map
-e --disable-mpls Disable MPLS
-v --version Print version info and exit
-s --source Use source src_addr for outgoing packets
-D --dev Use the following Network Devices as the
@@ -327,6 +381,7 @@ Arguments:
aliyun, dnspod, google, cloudflare]
-g --language Choose the language for displaying [en,
cn]. Default: cn
--file Read IP Address or domain name from file
```
## Project screenshot
@@ -335,14 +390,6 @@ Arguments:
![image](https://user-images.githubusercontent.com/59512455/218501311-1ceb9b79-79e6-4eb6-988a-9d38f626cdb8.png)
## NextTrace Enhanced
`NextTrace Enhanced` is an enhanced version for enthusiasts, `Enhanced` provides trace route calls in the form of Web API and a simple Looking Glass webpage with built-in visualization.
Please Notice that `NextTrace Enhanced` is currently not supported in English.
[https://github.com/OwO-Network/nexttrace-enhanced](https://github.com/OwO-Network/nexttrace-enhanced)
## OpenTrace
`OpenTrace` is the cross-platform `GUI` version of `NextTrace` developed by @Archeb, bringing a familiar but more powerful user experience.
@@ -351,6 +398,12 @@ This software is still in the early stages of development and may have many flaw
[https://github.com/Archeb/opentrace](https://github.com/Archeb/opentrace)
## NEXTTRACE WEB API
`NextTraceWebApi` is a web-based server implementation of `NextTrace` in the `MTR` style, offering various deployment options including `Docker`.
[https://github.com/nxtrace/nexttracewebapi](https://github.com/nxtrace/nexttracewebapi)
## LeoMoeAPI Credit
NextTrace focuses on Golang Traceroute implementations, and its LeoMoeAPI geolocation information is not supported by raw data, so a commercial version is not possible.
@@ -376,6 +429,8 @@ We hope you can give us as much feedback as possible on IP geolocation errors (s
## Credits
[sjlleo](https://github.com/sjlleo) The perpetual leader, founder, and core contributors of the NextTrace Project
[BGP.TOOLS](https://bgp.tools) provided some data support for this project. And we would like to express our sincere gratitude.
[Vincent Young](https://github.com/missuo) (i@yyt.moe)
@@ -393,12 +448,12 @@ We hope you can give us as much feedback as possible on IP geolocation errors (s
Although other third-party APIs are integrated in this project, please refer to the official website of the third-party APIs for specific TOS and AUP. If you encounter IP data errors, please contact them directly to correct them.
For feedback related to corrections about IP information, we currently have two channels available:
>- [IP 错误报告汇总帖](https://github.com/sjlleo/nexttrace/issues/41) in the GITHUB ISSUES section of this project (Recommended)
>- [IP 错误报告汇总帖](https://github.com/nxtrace/NTrace-core/issues/41) in the GITHUB ISSUES section of this project (Recommended)
>- This project's dedicated correction email: `correction@moeqing.com` (Please note that this email is only for correcting IP-related information. For other feedback, please submit an ISSUE)
How to obtain the freshly baked binary executable of the latest commit?
> Please go to the most recent [Build & Release](https://github.com/sjlleo/nexttrace/actions/workflows/build.yml) workflow in GitHub Actions.
> Please go to the most recent [Build & Release](https://github.com/nxtrace/Ntrace-V1/actions/workflows/build.yml) workflow in GitHub Actions.
## Star History
[![Star History Chart](https://api.star-history.com/svg?repos=sjlleo/nexttrace&type=Date)](https://star-history.com/#sjlleo/nexttrace&Date)
[![Star History Chart](https://api.star-history.com/svg?repos=nxtrace/NTrace-core&type=Date)](https://star-history.com/#nxtrace/NTrace-core&Date)

View File

@@ -12,54 +12,85 @@
<h4 align="center">一款追求轻量化的开源可视化路由跟踪工具。</h4>
<p align="center">
<a href="https://github.com/sjlleo/nexttrace/actions">
<img src="https://img.shields.io/github/actions/workflow/status/sjlleo/nexttrace/build.yml?branch=main&style=flat-square" alt="Github Actions">
<a href="https://github.com/nxtrace/Ntrace-V1/actions">
<img src="https://img.shields.io/github/actions/workflow/status/nxtrace/Ntrace-V1/build.yml?branch=main&style=flat-square" alt="Github Actions">
</a>
<a href="https://goreportcard.com/report/github.com/sjlleo/nexttrace">
<img src="https://goreportcard.com/badge/github.com/sjlleo/nexttrace?style=flat-square">
<a href="https://goreportcard.com/report/github.com/nxtrace/Ntrace-V1">
<img src="https://goreportcard.com/badge/github.com/nxtrace/Ntrace-V1?style=flat-square">
</a>
<a href="https://github.com/sjlleo/nexttrace/releases">
<img src="https://img.shields.io/github/release/sjlleo/nexttrace/all.svg?style=flat-square">
<a href="https://github.com/nxtrace/Ntrace-V1/releases">
<img src="https://img.shields.io/github/release/nxtrace/Ntrace-V1/all.svg?style=flat-square">
</a>
<a href="https://telegram.dog/sjprojects">
<img src="https://img.shields.io/endpoint?color=neon&style=flat-square&url=https%3A%2F%2Ftg.sumanjay.workers.dev%2Fnexttrace">
</a>
</p>
如果您喜欢这个项目,可以通过[爱发电支持](https://afdian.net/a/sjlleo/plan)我们项目的持续发展,您的捐助将用于服务器和 API 开支,非常感谢!
## IAAS Sponsor
<div style="text-align: center;">
<a href="https://dmit.io">
<img src="https://www.dmit.io/templates/dmit_theme_2020/dmit/assets/images/dmit_logo_with_text_blue.svg" width="170.7" height="62.9">
</a>
&nbsp;&nbsp;&nbsp;&nbsp;
<a href="https://misaka.io" >
<img src="https://www.jsdelivr.com/assets/8997e39e1f9d776502ab4d7cdff9d1608aa67aaf/img/globalping/sponsors/misaka.svg" width="170.7" height="62.9">
</a>
&nbsp;&nbsp;&nbsp;&nbsp;
<a href="https://skywolf.cloud" >
<img src="https://hk.skywolf.cloud/assets/img/skywolf.svg" width="170.7" height="62.9">
</a>
</div>
我们非常感谢 [DMIT](https://dmit.io) 和 [Misaka](https://misaka.io) 和 [Skywolf](https://skywolf.cloud) 提供了支持本项目所需的网络基础设施。
## How To Use
Document Language: [English](README.md) | 简体中文
⚠️ 请注意我们欢迎来自社区的PR提交但是请将您的PR提交至 [NTrace-V1](https://github.com/nxtrace/NTrace-V1) 仓库,而不是 [NTrace-core](https://github.com/nxtrace/NTrace-core) 仓库。<br>
关于NTrace-V1和NTrace-core两个仓库的说明<br>
二者将大体上保持一致。所有的开发工作均在NTrace-V1仓库中进行。NTrace-V1仓库首先发布新版本在稳定运行一段时间后时长不定我们会把版本同步至NTrace-core。这意味着NTrace-V1仓库充当了一个“测试版”的角色。<br>
请注意版本同步也存在例外。如果NTrace-V1的某个版本出现了严重的bugNTrace-core会跳过这一有缺陷的版本直接同步到下一个修复了该问题的版本。
### Before Using
使用 NextTrace 之前,我们建议您先阅读 [#IP 数据以及精准度说明](https://github.com/sjlleo/nexttrace/blob/main/README_zh_CN.md#ip-%E6%95%B0%E6%8D%AE%E4%BB%A5%E5%8F%8A%E7%B2%BE%E5%87%86%E5%BA%A6%E8%AF%B4%E6%98%8E),在了解您自己的对数据精准度需求以后再进行抉择。
使用 NextTrace 之前,我们建议您先阅读 [#IP 数据以及精准度说明](https://github.com/nxtrace/NTrace-core/blob/main/README_zh_CN.md#ip-%E6%95%B0%E6%8D%AE%E4%BB%A5%E5%8F%8A%E7%B2%BE%E5%87%86%E5%BA%A6%E8%AF%B4%E6%98%8E),在了解您自己的对数据精准度需求以后再进行抉择。
[NextTrace 的Telegram频道](https://t.me/nexttrace)由项目成员负责,会传递一部分通知,也会发布一些成员自己分享的小工具。项目成员的意见可作为未来项目发展的可能方向,随着开发进度变化可能会有所改动,不代表未来一定会实装,正式定稿公告会发布于 Issue 中。
### Automated Install
* Linux
* 一键安装脚本
* Github下载
```shell
bash -c "$(curl -Ls https://github.com/sjlleo/nexttrace/raw/main/nt_install.sh)"
```
* GHPROXY镜像中国大陆使用
```shell
bash -c "$(curl -Ls https://ghproxy.com/https://github.com/sjlleo/nexttrace/raw/main/nt_install.sh)"
```
```shell
bash -c "$(curl http://nexttrace-io-leomoe-api-a0.shop/nt_install_v1.sh)"
```
* Arch Linux AUR 安装命令
* 由源码构建
```shell
yay -S nexttrace
```
* 直接下载bin包(仅支持amd64)
```shell
yay -S nexttrace-bin`
```
* AUR 的2种构建分别由 huyz 和 ouuan 维护
* AUR 的构建分别由 ouuan 维护
* Linuxbrew 安装命令
同macOS Homebrew安装方法(homebrew-core版仅支持amd64)
* Deepin 安装命令
```shell
apt install nexttrace
```
* Termux 安装命令
```shell
pkg install nexttrace-enhanced
```
* macOS
* macOS Homebrew 安装命令
@@ -71,7 +102,7 @@
* 本仓库ACTIONS自动构建版(更新更快)
```shell
brew tap xgadget-lab/nexttrace && brew install nexttrace
brew tap nxtrace/nexttrace && brew install nxtrace/nexttrace/nexttrace
```
* homebrew-core 构建由 chenrui333 维护请注意该版本更新可能会落后仓库Action自动构建版本
@@ -90,7 +121,7 @@
### Manual Install
* 下载预编译的可执行程序
对于以上方法没有涵盖的用户,请直接前往 [Release](https://github.com/sjlleo/nexttrace/releases/latest) 下载编译后的二进制可执行文件。
对于以上方法没有涵盖的用户,请直接前往 [Release](https://github.com/nxtrace/Ntrace-V1/releases/latest) 下载编译后的二进制可执行文件。
* `Release`里面为很多系统以及不同架构提供了编译好的二进制可执行文件,如果没有可以自行编译。
* 一些本项目的必要依赖在`Windows`上`Golang`底层实现不完全,所以目前`NextTrace`在`Windows`平台出于实验性支持阶段。
@@ -100,7 +131,7 @@
您可在自行安装Go >= 1.20后,使用以下命令安装
```shell
go install github.com/xgadget-lab/nexttrace@latest
go install github.com/nxtrace/Ntrace-V1@latest
```
安装后可执行文件在`$GOPATH/bin`目录下,如果您没有设置`GOPATH`,则在`$HOME/go/bin`目录下。
@@ -132,6 +163,10 @@ nexttrace 2606:4700:4700::1111
# 禁用路径可视化 使用 --map / -M 参数
nexttrace koreacentral.blob.core.windows.net
# MapTrace URL: https://api.leo.moe/tracemap/html/c14e439e-3250-5310-8965-42a1e3545266.html
# 禁用MPLS显示 使用 --disable-mpls / -e 参数 或 NEXTTRACE_DISABLEMPLS 环境变量
nexttrace --disable-mpls example.com
export NEXTTRACE_DISABLEMPLS=1
```
PS: 路由可视化的绘制模块由 [@tsosunchia](https://github.com/tsosunchia) 同学编写,具体代码可在 [tsosunchia/traceMap](https://github.com/tsosunchia/traceMap) 查看
@@ -148,6 +183,17 @@ nexttrace --fast-trace
# 也可以使用 TCP SYN 而非 ICMP 进行测试
nexttrace --fast-trace --tcp
# 也可以通过自定义的IP/DOMAIN列表文件进行快速测试
nexttrace --file /path/to/your/iplist.txt
# 自定义的IP/DOMAIN列表文件格式
## 一行一个IP/DOMAIN + 空格 + 描述信息(可选)
## 例如:
## 106.37.67.1 北京电信
## 240e:928:101:31a::1 北京电信
## bj.10086.cn 北京移动
## 2409:8080:0:1::1
## 223.5.5.5
```
`NextTrace` 已支持指定网卡进行路由跟踪
@@ -288,6 +334,9 @@ Arguments:
IPInfo, IPInsight, IP-API.com, Ip2region,
IPInfoLocal, CHUNZHEN, disable-geoip].
Default: LeoMoeAPI
--pow-provider Choose PoW Provider [api.leo.moe, sakura]
For China mainland users, please use
sakura. Default: api.leo.moe
-n --no-rdns Do not resolve IP addresses to their
domain names
-a --always-rdns Always resolve IP addresses to their
@@ -306,6 +355,7 @@ Arguments:
-f --first Start from the first_ttl hop (instead from
1). Default: 1
-M --map Disable Print Trace Map
-e --disable-mpls Disable MPLS
-v --version Print version info and exit
-s --source Use source src_addr for outgoing packets
-D --dev Use the following Network Devices as the
@@ -329,6 +379,7 @@ Arguments:
aliyun, dnspod, google, cloudflare]
-g --language Choose the language for displaying [en,
cn]. Default: cn
--file Read IP Address or domain name from file
```
## 项目截图
@@ -339,7 +390,7 @@ Arguments:
## 第三方 IP 数据库 API 开发接口
NextTrace 所有的的 IP 地理位置 `API DEMO` 可以参考[这里](https://github.com/sjlleo/nexttrace/blob/main/ipgeo/)
NextTrace 所有的的 IP 地理位置 `API DEMO` 可以参考[这里](https://github.com/nxtrace/NTrace-core/blob/main/ipgeo/)
你可以在这里添加你自己的 API 接口,为了 NextTrace 能够正确显示你接口中的内容,请参考 `leo.go` 中所需要的信息
@@ -351,11 +402,14 @@ NextTrace `LeoMoeAPI`现已使用Proof of Work(POW)机制来防止滥用,其
- [GitHub - tsosunchia/powclient: Proof of Work CLIENT for NextTrace](https://github.com/tsosunchia/powclient)
- [GitHub - tsosunchia/powserver: Proof of Work SERVER for NextTrace](https://github.com/tsosunchia/powserver)
```go
## NextTrace Enhanced
[https://github.com/OwO-Network/nexttrace-enhanced](https://github.com/OwO-Network/nexttrace-enhanced)
对于中国大陆用户,可以使用 [Nya Labs](https://natfrp.com) 提供的位于大陆的POW服务器优化访问速度
```shell
#使用方法任选其一
#1. 在环境变量中设置
export NEXTTRACE_POWPROVIDER=sakura
#2. 在命令行中设置
nexttrace --pow-provider sakura
```
## OpenTrace
@@ -365,8 +419,16 @@ NextTrace `LeoMoeAPI`现已使用Proof of Work(POW)机制来防止滥用,其
[https://github.com/Archeb/opentrace](https://github.com/Archeb/opentrace)
## NEXTTRACE WEB API
`NextTraceWebApi`是一个`MTR`风格的`NextTrace`网页版服务端实现,提供了包括`Docker`在内多种部署方式。
[https://github.com/nxtrace/nexttracewebapi](https://github.com/nxtrace/nexttracewebapi)
## Credits
[sjlleo](https://github.com/sjlleo) NextTrace 项目永远的领导者、创始人及核心贡献者
[BGP.TOOLS](https://bgp.tools) 提供了本项目的一些数据支持,在此表示由衷地感谢。
[Vincent Young](https://github.com/missuo) (i@yyt.moe)
@@ -384,12 +446,12 @@ NextTrace `LeoMoeAPI`现已使用Proof of Work(POW)机制来防止滥用,其
其他第三方 API 尽管集成在本项目内,但是具体的 TOS 以及 AUP请详见第三方 API 官网。如遇到 IP 数据错误,也请直接联系他们纠错。
如何获取最新commit的新鲜出炉的二进制可执行文件
>请前往GitHub Actions中最新一次 [Build & Release](https://github.com/sjlleo/nexttrace/actions/workflows/build.yml) workflow.
>请前往GitHub Actions中最新一次 [Build & Release](https://github.com/nxtrace/Ntrace-V1/actions/workflows/build.yml) workflow.
## IP 数据以及精准度说明
对于IP相关信息的纠错反馈我们目前开放了两个渠道
>- 本项目的GITHUB ISSUES区中的[IP 错误报告汇总帖](https://github.com/sjlleo/nexttrace/issues/41)
>- 本项目的GITHUB ISSUES区中的[IP 错误报告汇总帖](https://github.com/nxtrace/NTrace-core/issues/41)
>- 本项目的纠错专用邮箱: `correction@moeqing.com` 请注意此邮箱仅供IP相关信息纠错专用其他反馈请发送ISSUE
NextTrace 有多个数据源可以选择,目前默认使用的 LeoMoeAPI 为我们项目维护的数据源。
@@ -447,3 +509,9 @@ LAX,US,California,Los Anegles
```
需要注意的是NextTrace 支持自动匹配 CSV 中的城市名,如果您的 PTR 记录中有 `losangeles`,您可以只添加上面一条记录就可以正常识别并读取。
rkflow in GitHub Actions.
## Star History
[![Star History Chart](https://api.star-history.com/svg?repos=nxtrace/NTrace-core&type=Date)](https://star-history.com/#nxtrace/NTrace-core&Date)

View File

@@ -12,17 +12,17 @@ import (
"time"
"github.com/akamensky/argparse"
"github.com/nxtrace/NTrace-core/config"
fastTrace "github.com/nxtrace/NTrace-core/fast_trace"
"github.com/nxtrace/NTrace-core/ipgeo"
"github.com/nxtrace/NTrace-core/printer"
"github.com/nxtrace/NTrace-core/reporter"
"github.com/nxtrace/NTrace-core/trace"
"github.com/nxtrace/NTrace-core/tracelog"
"github.com/nxtrace/NTrace-core/tracemap"
"github.com/nxtrace/NTrace-core/util"
"github.com/nxtrace/NTrace-core/wshandle"
"github.com/syndtr/gocapability/capability"
"github.com/xgadget-lab/nexttrace/config"
fastTrace "github.com/xgadget-lab/nexttrace/fast_trace"
"github.com/xgadget-lab/nexttrace/ipgeo"
"github.com/xgadget-lab/nexttrace/printer"
"github.com/xgadget-lab/nexttrace/reporter"
"github.com/xgadget-lab/nexttrace/trace"
"github.com/xgadget-lab/nexttrace/tracelog"
"github.com/xgadget-lab/nexttrace/tracemap"
"github.com/xgadget-lab/nexttrace/util"
"github.com/xgadget-lab/nexttrace/wshandle"
)
func Excute() {
@@ -41,6 +41,8 @@ func Excute() {
maxHops := parser.Int("m", "max-hops", &argparse.Options{Default: 30, Help: "Set the max number of hops (max TTL to be reached)"})
dataOrigin := parser.Selector("d", "data-provider", []string{"Ip2region", "ip2region", "IP.SB", "ip.sb", "IPInfo", "ipinfo", "IPInsight", "ipinsight", "IPAPI.com", "ip-api.com", "IPInfoLocal", "ipinfolocal", "chunzhen", "LeoMoeAPI", "leomoeapi", "disable-geoip"}, &argparse.Options{Default: "LeoMoeAPI",
Help: "Choose IP Geograph Data Provider [IP.SB, IPInfo, IPInsight, IP-API.com, Ip2region, IPInfoLocal, CHUNZHEN, disable-geoip]"})
powProvider := parser.Selector("", "pow-provider", []string{"api.leo.moe", "sakura"}, &argparse.Options{Default: "api.leo.moe",
Help: "Choose PoW Provider [api.leo.moe, sakura] For China mainland users, please use sakura"})
noRdns := parser.Flag("n", "no-rdns", &argparse.Options{Help: "Do not resolve IP addresses to their domain names"})
alwaysRdns := parser.Flag("a", "always-rdns", &argparse.Options{Help: "Always resolve IP addresses to their domain names"})
routePath := parser.Flag("P", "route-path", &argparse.Options{Help: "Print traceroute hop path by ASN and location"})
@@ -53,6 +55,7 @@ func Excute() {
classicPrint := parser.Flag("c", "classic", &argparse.Options{Help: "Classic Output trace results like BestTrace"})
beginHop := parser.Int("f", "first", &argparse.Options{Default: 1, Help: "Start from the first_ttl hop (instead from 1)"})
disableMaptrace := parser.Flag("M", "map", &argparse.Options{Help: "Disable Print Trace Map"})
disableMPLS := parser.Flag("e", "disable-mpls", &argparse.Options{Help: "Disable MPLS"})
ver := parser.Flag("v", "version", &argparse.Options{Help: "Print version info and exit"})
srcAddr := parser.String("s", "source", &argparse.Options{Help: "Use source src_addr for outgoing packets"})
srcDev := parser.String("D", "dev", &argparse.Options{Help: "Use the following Network Devices as the source address in outgoing packets"})
@@ -66,6 +69,7 @@ func Excute() {
Help: "Use DoT Server for DNS Parse [dnssb, aliyun, dnspod, google, cloudflare]"})
lang := parser.Selector("g", "language", []string{"en", "cn"}, &argparse.Options{Default: "cn",
Help: "Choose the language for displaying [en, cn]"})
file := parser.String("", "file", &argparse.Options{Help: "Read IP Address or domain name from file"})
err := parser.Parse(os.Args)
if err != nil {
@@ -88,7 +92,7 @@ func Excute() {
*port = 80
}
if *fast_trace {
if *fast_trace || *file != "" {
var paramsFastTrace = fastTrace.ParamsFastTrace{
SrcDev: *srcDev,
SrcAddr: *srcAddr,
@@ -99,6 +103,7 @@ func Excute() {
Lang: *lang,
PktSize: *packetSize,
Timeout: time.Duration(*timeout) * time.Millisecond,
File: *file,
}
fastTrace.FastTest(*tcp, *output, paramsFastTrace)
@@ -155,6 +160,9 @@ func Excute() {
// defer wg.Done()
if strings.ToUpper(*dataOrigin) == "LEOMOEAPI" {
val, ok := os.LookupEnv("NEXTTRACE_DATAPROVIDER")
if strings.ToUpper(*powProvider) != "API.LEO.MOE" {
util.PowProviderParam = *powProvider
}
if ok {
*dataOrigin = val
} else {
@@ -170,32 +178,44 @@ func Excute() {
//
//go func() {
// defer wg.Done()
err = nil
if *udp {
if *ipv6Only {
fmt.Println("[Info] IPv6 UDP Traceroute is not supported right now.")
os.Exit(0)
}
ip = util.DomainLookUp(domain, "4", *dot, *jsonPrint)
ip, err = util.DomainLookUp(domain, "4", *dot, *jsonPrint)
} else {
if *ipv6Only {
ip = util.DomainLookUp(domain, "6", *dot, *jsonPrint)
ip, err = util.DomainLookUp(domain, "6", *dot, *jsonPrint)
} else if *ipv4Only {
ip = util.DomainLookUp(domain, "4", *dot, *jsonPrint)
ip, err = util.DomainLookUp(domain, "4", *dot, *jsonPrint)
} else {
ip = util.DomainLookUp(domain, "all", *dot, *jsonPrint)
ip, err = util.DomainLookUp(domain, "all", *dot, *jsonPrint)
}
}
if err != nil {
fmt.Println(err)
os.Exit(1)
}
//}()
//
//wg.Wait()
if *srcDev != "" {
dev, _ := net.InterfaceByName(*srcDev)
if addrs, err := dev.Addrs(); err == nil {
for _, addr := range addrs {
if (addr.(*net.IPNet).IP.To4() == nil) == (ip.To4() == nil) {
*srcAddr = addr.(*net.IPNet).IP.String()
// 检查是否是内网IP
if !(net.ParseIP(*srcAddr).IsPrivate() ||
net.ParseIP(*srcAddr).IsLoopback() ||
net.ParseIP(*srcAddr).IsLinkLocalUnicast() ||
net.ParseIP(*srcAddr).IsLinkLocalMulticast()) {
// 若不是则跳出
break
}
}
}
}
@@ -205,7 +225,7 @@ func Excute() {
printer.PrintTraceRouteNav(ip, domain, *dataOrigin, *maxHops, *packetSize)
}
var m trace.Method = ""
var m trace.Method
switch {
case *tcp:
@@ -274,6 +294,10 @@ func Excute() {
}
}
if *disableMPLS {
util.DisableMPLS = "1"
}
res, err := trace.Traceroute(m, conf)
if err != nil {
@@ -294,7 +318,8 @@ func Excute() {
fmt.Println(err)
return
}
if !*disableMaptrace && strings.ToUpper(*dataOrigin) == "LEOMOEAPI" {
if !*disableMaptrace &&
(util.StringInSlice(strings.ToUpper(*dataOrigin), []string{"LEOMOEAPI", "IPINFO", "IPINFO", "IP-API.COM", "IPAPI.COM"})) {
url, err := tracemap.GetMapUrl(string(r))
if err != nil {
log.Fatalln(err)

View File

@@ -175,12 +175,12 @@ var Hefei = BackBoneCollection{
// 中国科学技术大学 教育网
EDU: ISPCollection{
ISPName: EDU,
IP: "ipv4.hef-4538.nexttrace-io-fasttrace-endpoint.win.",
IPv6: "ipv6.hef-4538.nexttrace-io-fasttrace-endpoint.win.",
IP: "ipv4.hfe-4538.nexttrace-io-fasttrace-endpoint.win.",
IPv6: "ipv6.hfe-4538.nexttrace-io-fasttrace-endpoint.win.",
},
// 中国科学技术大学 科技网
CST: ISPCollection{
ISPName: "中国科学技术大学 科技网 AS7497",
IP: "ipv4.hef-7497.nexttrace-io-fasttrace-endpoint.win.",
IP: "ipv4.hfe-7497.nexttrace-io-fasttrace-endpoint.win.",
},
}

View File

@@ -2,56 +2,60 @@ package fastTrace
import (
"fmt"
"github.com/xgadget-lab/nexttrace/ipgeo"
"github.com/xgadget-lab/nexttrace/printer"
"github.com/xgadget-lab/nexttrace/trace"
"github.com/xgadget-lab/nexttrace/tracelog"
"github.com/xgadget-lab/nexttrace/util"
"github.com/xgadget-lab/nexttrace/wshandle"
"github.com/nxtrace/NTrace-core/ipgeo"
"github.com/nxtrace/NTrace-core/printer"
"github.com/nxtrace/NTrace-core/trace"
"github.com/nxtrace/NTrace-core/tracelog"
"github.com/nxtrace/NTrace-core/util"
"github.com/nxtrace/NTrace-core/wshandle"
"log"
"os"
"os/signal"
)
var pFastTracer ParamsFastTrace
//var pFastTracer ParamsFastTrace
func (f *FastTracer) tracert_v6(location string, ispCollection ISPCollection) {
fp, err := os.OpenFile("/tmp/trace.log", os.O_CREATE|os.O_APPEND|os.O_RDWR, os.ModePerm)
if err != nil {
return
}
defer func(fp *os.File) {
err := fp.Close()
if err != nil {
log.Fatal(err)
}
}(fp)
log.SetOutput(fp)
log.SetFlags(0)
fmt.Printf("%s『%s %s 』%s\n", printer.YELLOW_PREFIX, location, ispCollection.ISPName, printer.RESET_PREFIX)
log.Printf("%s %s 』\n", location, ispCollection.ISPName)
fmt.Printf("traceroute to %s, %d hops max, %d byte packets\n", ispCollection.IPv6, pFastTracer.MaxHops, pFastTracer.PktSize)
log.Printf("traceroute to %s, %d hops max, %d byte packets\n", ispCollection.IPv6, pFastTracer.MaxHops, pFastTracer.PktSize)
ip := util.DomainLookUp(ispCollection.IPv6, "6", "", true)
fmt.Printf("traceroute to %s, %d hops max, %d byte packets\n", ispCollection.IPv6, f.ParamsFastTrace.MaxHops, f.ParamsFastTrace.PktSize)
ip, err := util.DomainLookUp(ispCollection.IPv6, "6", "", true)
if err != nil {
log.Fatal(err)
}
var conf = trace.Config{
BeginHop: pFastTracer.BeginHop,
BeginHop: f.ParamsFastTrace.BeginHop,
DestIP: ip,
DestPort: 80,
MaxHops: pFastTracer.MaxHops,
MaxHops: f.ParamsFastTrace.MaxHops,
NumMeasurements: 3,
ParallelRequests: 18,
RDns: pFastTracer.RDns,
AlwaysWaitRDNS: pFastTracer.AlwaysWaitRDNS,
RDns: f.ParamsFastTrace.RDns,
AlwaysWaitRDNS: f.ParamsFastTrace.AlwaysWaitRDNS,
PacketInterval: 100,
TTLInterval: 500,
IPGeoSource: ipgeo.GetSource("LeoMoeAPI"),
Timeout: pFastTracer.Timeout,
PktSize: pFastTracer.PktSize,
Lang: pFastTracer.Lang,
Timeout: f.ParamsFastTrace.Timeout,
SrcAddr: f.ParamsFastTrace.SrcAddr,
PktSize: f.ParamsFastTrace.PktSize,
Lang: f.ParamsFastTrace.Lang,
}
if oe {
fp, err := os.OpenFile("/tmp/trace.log", os.O_CREATE|os.O_APPEND|os.O_RDWR, os.ModePerm)
if err != nil {
return
}
defer func(fp *os.File) {
err := fp.Close()
if err != nil {
log.Fatal(err)
}
}(fp)
log.SetOutput(fp)
log.SetFlags(0)
log.Printf("『%s %s 』\n", location, ispCollection.ISPName)
log.Printf("traceroute to %s, %d hops max, %d byte packets\n", ispCollection.IPv6, f.ParamsFastTrace.MaxHops, f.ParamsFastTrace.PktSize)
conf.RealtimePrinter = tracelog.RealtimePrinter
} else {
conf.RealtimePrinter = printer.RealtimePrinter
@@ -63,7 +67,7 @@ func (f *FastTracer) tracert_v6(location string, ispCollection ISPCollection) {
log.Fatal(err)
}
println()
fmt.Println()
}
func (f *FastTracer) testAll_v6() {
@@ -103,20 +107,28 @@ func (f *FastTracer) testEDU_v6() {
f.tracert_v6(TestIPsCollection.Hangzhou.Location, TestIPsCollection.Hangzhou.EDU)
}
func (f *FastTracer) testFast_v6() {
f.tracert_v6(TestIPsCollection.Beijing.Location, TestIPsCollection.Beijing.CT163)
f.tracert_v6(TestIPsCollection.Beijing.Location, TestIPsCollection.Beijing.CU169)
f.tracert_v6(TestIPsCollection.Beijing.Location, TestIPsCollection.Beijing.CM)
f.tracert_v6(TestIPsCollection.Beijing.Location, TestIPsCollection.Beijing.EDU)
}
func FastTestv6(tm bool, outEnable bool, paramsFastTrace ParamsFastTrace) {
var c string
oe = outEnable
pFastTracer = paramsFastTrace
fmt.Println("您想测试哪些ISP的路由\n1. 国内四网\n2. 电信\n3. 联通\n4. 移动\n5. 教育网")
fmt.Println("您想测试哪些ISP的路由\n1. 国内四网\n2. 电信\n3. 联通\n4. 移动\n5. 教育网\n6. 全部")
fmt.Print("请选择选项:")
_, err := fmt.Scanln(&c)
if err != nil {
c = "1"
}
ft := FastTracer{}
ft := FastTracer{
ParamsFastTrace: paramsFastTrace,
}
// 建立 WebSocket 连接
w := wshandle.New()
@@ -135,7 +147,7 @@ func FastTestv6(tm bool, outEnable bool, paramsFastTrace ParamsFastTrace) {
switch c {
case "1":
ft.testAll_v6()
ft.testFast_v6()
case "2":
ft.testCT_v6()
case "3":
@@ -144,7 +156,9 @@ func FastTestv6(tm bool, outEnable bool, paramsFastTrace ParamsFastTrace) {
ft.testCM_v6()
case "5":
ft.testEDU_v6()
default:
case "6":
ft.testAll_v6()
default:
ft.testFast_v6()
}
}

View File

@@ -1,17 +1,19 @@
package fastTrace
import (
"bufio"
"fmt"
"github.com/xgadget-lab/nexttrace/ipgeo"
"github.com/xgadget-lab/nexttrace/printer"
"github.com/xgadget-lab/nexttrace/trace"
"github.com/xgadget-lab/nexttrace/tracelog"
"github.com/xgadget-lab/nexttrace/util"
"github.com/xgadget-lab/nexttrace/wshandle"
"github.com/nxtrace/NTrace-core/ipgeo"
"github.com/nxtrace/NTrace-core/printer"
"github.com/nxtrace/NTrace-core/trace"
"github.com/nxtrace/NTrace-core/tracelog"
"github.com/nxtrace/NTrace-core/util"
"github.com/nxtrace/NTrace-core/wshandle"
"log"
"net"
"os"
"os/signal"
"strings"
"time"
)
@@ -30,29 +32,25 @@ type ParamsFastTrace struct {
Lang string
PktSize int
Timeout time.Duration
File string
}
type IpListElement struct {
Ip string
Desc string
Version4 bool // true for IPv4, false for IPv6
}
var oe = false
func (f *FastTracer) tracert(location string, ispCollection ISPCollection) {
fp, err := os.OpenFile("/tmp/trace.log", os.O_CREATE|os.O_APPEND|os.O_RDWR, os.ModePerm)
if err != nil {
return
}
defer func(fp *os.File) {
err := fp.Close()
if err != nil {
log.Fatal(err)
}
}(fp)
log.SetOutput(fp)
log.SetFlags(0)
fmt.Printf("%s『%s %s 』%s\n", printer.YELLOW_PREFIX, location, ispCollection.ISPName, printer.RESET_PREFIX)
log.Printf("『%s %s 』\n", location, ispCollection.ISPName)
fmt.Printf("traceroute to %s, %d hops max, %d byte packets\n", ispCollection.IP, f.ParamsFastTrace.MaxHops, f.ParamsFastTrace.PktSize)
log.Printf("traceroute to %s, %d hops max, %d byte packets\n", ispCollection.IP, f.ParamsFastTrace.MaxHops, f.ParamsFastTrace.PktSize)
ip := util.DomainLookUp(ispCollection.IP, "4", "", true)
ip, err := util.DomainLookUp(ispCollection.IP, "4", "", true)
if err != nil {
log.Fatal(err)
}
var conf = trace.Config{
BeginHop: f.ParamsFastTrace.BeginHop,
DestIP: ip,
@@ -72,6 +70,21 @@ func (f *FastTracer) tracert(location string, ispCollection ISPCollection) {
}
if oe {
fp, err := os.OpenFile("/tmp/trace.log", os.O_CREATE|os.O_APPEND|os.O_RDWR, os.ModePerm)
if err != nil {
return
}
defer func(fp *os.File) {
err := fp.Close()
if err != nil {
log.Fatal(err)
}
}(fp)
log.SetOutput(fp)
log.SetFlags(0)
log.Printf("『%s %s 』\n", location, ispCollection.ISPName)
log.Printf("traceroute to %s, %d hops max, %d byte packets\n", ispCollection.IP, f.ParamsFastTrace.MaxHops, f.ParamsFastTrace.PktSize)
conf.RealtimePrinter = tracelog.RealtimePrinter
} else {
conf.RealtimePrinter = printer.RealtimePrinter
@@ -82,13 +95,19 @@ func (f *FastTracer) tracert(location string, ispCollection ISPCollection) {
if err != nil {
log.Fatal(err)
}
println()
fmt.Println()
}
func FastTest(tm bool, outEnable bool, paramsFastTrace ParamsFastTrace) {
// tm means tcp mode
var c string
pFastTrace := paramsFastTrace
oe = outEnable
if paramsFastTrace.File != "" {
testFile(paramsFastTrace, tm)
return
}
fmt.Println("Hi欢迎使用 Fast Trace 功能,请注意 Fast Trace 功能只适合新手使用\n因为国内网络复杂我们设置的测试目标有限建议普通用户自测以获得更加精准的路由情况")
fmt.Println("请您选择要测试的 IP 类型\n1. IPv4\n2. IPv6")
fmt.Print("请选择选项:")
@@ -97,22 +116,47 @@ func FastTest(tm bool, outEnable bool, paramsFastTrace ParamsFastTrace) {
c = "1"
}
if c == "2" {
if paramsFastTrace.SrcDev != "" {
dev, _ := net.InterfaceByName(paramsFastTrace.SrcDev)
if addrs, err := dev.Addrs(); err == nil {
for _, addr := range addrs {
if (addr.(*net.IPNet).IP.To4() == nil) == true {
paramsFastTrace.SrcAddr = addr.(*net.IPNet).IP.String()
// 检查是否是内网IP
if !(net.ParseIP(paramsFastTrace.SrcAddr).IsPrivate() ||
net.ParseIP(paramsFastTrace.SrcAddr).IsLoopback() ||
net.ParseIP(paramsFastTrace.SrcAddr).IsLinkLocalUnicast() ||
net.ParseIP(paramsFastTrace.SrcAddr).IsLinkLocalMulticast()) {
// 若不是则跳出
break
}
}
}
}
}
FastTestv6(tm, outEnable, paramsFastTrace)
return
}
if pFastTrace.SrcDev != "" {
dev, _ := net.InterfaceByName(pFastTrace.SrcDev)
if paramsFastTrace.SrcDev != "" {
dev, _ := net.InterfaceByName(paramsFastTrace.SrcDev)
if addrs, err := dev.Addrs(); err == nil {
for _, addr := range addrs {
if addr.(*net.IPNet).IP.To4() != nil {
pFastTrace.SrcAddr = addr.(*net.IPNet).IP.String()
if (addr.(*net.IPNet).IP.To4() == nil) == false {
paramsFastTrace.SrcAddr = addr.(*net.IPNet).IP.String()
// 检查是否是内网IP
if !(net.ParseIP(paramsFastTrace.SrcAddr).IsPrivate() ||
net.ParseIP(paramsFastTrace.SrcAddr).IsLoopback() ||
net.ParseIP(paramsFastTrace.SrcAddr).IsLinkLocalUnicast() ||
net.ParseIP(paramsFastTrace.SrcAddr).IsLinkLocalMulticast()) {
// 若不是则跳出
break
}
}
}
}
}
fmt.Println("您想测试哪些ISP的路由\n1. 国内四网\n2. 电信\n3. 联通\n4. 移动\n5. 教育网")
fmt.Println("您想测试哪些ISP的路由\n1. 国内四网\n2. 电信\n3. 联通\n4. 移动\n5. 教育网\n6. 全部")
fmt.Print("请选择选项:")
_, err = fmt.Scanln(&c)
if err != nil {
@@ -120,7 +164,7 @@ func FastTest(tm bool, outEnable bool, paramsFastTrace ParamsFastTrace) {
}
ft := FastTracer{
ParamsFastTrace: pFastTrace,
ParamsFastTrace: paramsFastTrace,
}
// 建立 WebSocket 连接
@@ -140,7 +184,7 @@ func FastTest(tm bool, outEnable bool, paramsFastTrace ParamsFastTrace) {
switch c {
case "1":
ft.testAll()
ft.testFast()
case "2":
ft.testCT()
case "3":
@@ -149,11 +193,178 @@ func FastTest(tm bool, outEnable bool, paramsFastTrace ParamsFastTrace) {
ft.testCM()
case "5":
ft.testEDU()
default:
case "6":
ft.testAll()
default:
ft.testFast()
}
}
func testFile(paramsFastTrace ParamsFastTrace, tm bool) {
// 建立 WebSocket 连接
w := wshandle.New()
w.Interrupt = make(chan os.Signal, 1)
signal.Notify(w.Interrupt, os.Interrupt)
defer func() {
w.Conn.Close()
}()
var tracerouteMethod trace.Method
if !tm {
tracerouteMethod = trace.ICMPTrace
fmt.Println("您将默认使用ICMP协议进行路由跟踪如果您想使用TCP SYN进行路由跟踪可以加入 -T 参数")
} else {
tracerouteMethod = trace.TCPTrace
}
filePath := paramsFastTrace.File
file, err := os.Open(filePath)
if err != nil {
fmt.Println("Error opening file:", err)
return
}
defer func(file *os.File) {
err := file.Close()
if err != nil {
log.Fatal(err)
}
}(file)
var ipList []IpListElement
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
parts := strings.SplitN(line, " ", 2)
var ip, desc string
if len(parts) == 2 {
ip = parts[0]
desc = parts[1]
} else if len(parts) == 1 {
ip = parts[0]
desc = ip // Set the description to the IP if no description is provided
} else {
fmt.Printf("Ignoring invalid line: %s\n", line)
continue
}
parsedIP := net.ParseIP(ip)
if parsedIP == nil {
netIp, err := util.DomainLookUp(ip, "all", "", true)
if err != nil {
fmt.Printf("Ignoring invalid IP: %s\n", ip)
continue
}
if len(parts) == 1 {
desc = ip
}
ip = netIp.String()
}
ipElem := IpListElement{
Ip: ip,
Desc: desc,
Version4: strings.Contains(ip, "."),
}
ipList = append(ipList, ipElem)
}
if err := scanner.Err(); err != nil {
fmt.Println("Error reading file:", err)
}
for _, ip := range ipList {
fmt.Printf("%s『%s』%s\n", printer.YELLOW_PREFIX, ip.Desc, printer.RESET_PREFIX)
fmt.Printf("traceroute to %s, %d hops max, %d byte packets\n", ip.Ip, paramsFastTrace.MaxHops, paramsFastTrace.PktSize)
var srcAddr string
if ip.Version4 {
if paramsFastTrace.SrcDev != "" {
dev, _ := net.InterfaceByName(paramsFastTrace.SrcDev)
if addrs, err := dev.Addrs(); err == nil {
for _, addr := range addrs {
if (addr.(*net.IPNet).IP.To4() == nil) == false {
srcAddr = addr.(*net.IPNet).IP.String()
// 检查是否是内网IP
if !(net.ParseIP(srcAddr).IsPrivate() ||
net.ParseIP(srcAddr).IsLoopback() ||
net.ParseIP(srcAddr).IsLinkLocalUnicast() ||
net.ParseIP(srcAddr).IsLinkLocalMulticast()) {
// 若不是则跳出
break
}
}
}
}
}
} else {
if paramsFastTrace.SrcDev != "" {
dev, _ := net.InterfaceByName(paramsFastTrace.SrcDev)
if addrs, err := dev.Addrs(); err == nil {
for _, addr := range addrs {
if (addr.(*net.IPNet).IP.To4() == nil) == true {
srcAddr = addr.(*net.IPNet).IP.String()
// 检查是否是内网IP
if !(net.ParseIP(srcAddr).IsPrivate() ||
net.ParseIP(srcAddr).IsLoopback() ||
net.ParseIP(srcAddr).IsLinkLocalUnicast() ||
net.ParseIP(srcAddr).IsLinkLocalMulticast()) {
// 若不是则跳出
break
}
}
}
}
}
}
var conf = trace.Config{
BeginHop: paramsFastTrace.BeginHop,
DestIP: net.ParseIP(ip.Ip),
DestPort: 80,
MaxHops: paramsFastTrace.MaxHops,
NumMeasurements: 3,
ParallelRequests: 18,
RDns: paramsFastTrace.RDns,
AlwaysWaitRDNS: paramsFastTrace.AlwaysWaitRDNS,
PacketInterval: 100,
TTLInterval: 500,
IPGeoSource: ipgeo.GetSource("LeoMoeAPI"),
Timeout: paramsFastTrace.Timeout,
SrcAddr: srcAddr,
PktSize: paramsFastTrace.PktSize,
Lang: paramsFastTrace.Lang,
}
if oe {
fp, err := os.OpenFile("/tmp/trace.log", os.O_CREATE|os.O_APPEND|os.O_RDWR, os.ModePerm)
if err != nil {
return
}
defer func(fp *os.File) {
err := fp.Close()
if err != nil {
log.Fatal(err)
}
}(fp)
log.SetOutput(fp)
log.SetFlags(0)
log.Printf("『%s』\n", ip.Desc)
log.Printf("traceroute to %s, %d hops max, %d byte packets\n", ip.Ip, paramsFastTrace.MaxHops, paramsFastTrace.PktSize)
conf.RealtimePrinter = tracelog.RealtimePrinter
} else {
conf.RealtimePrinter = printer.RealtimePrinter
}
_, err := trace.Traceroute(tracerouteMethod, conf)
if err != nil {
log.Fatalln(err)
}
fmt.Println()
}
}
func (f *FastTracer) testAll() {
f.testCT()
println()
@@ -197,3 +408,10 @@ func (f *FastTracer) testEDU() {
// 科技网暂时算在EDU里面等拿到了足够多的数据再分离出去单独用于测试
f.tracert(TestIPsCollection.Hefei.Location, TestIPsCollection.Hefei.CST)
}
func (f *FastTracer) testFast() {
f.tracert(TestIPsCollection.Beijing.Location, TestIPsCollection.Beijing.CT163)
f.tracert(TestIPsCollection.Beijing.Location, TestIPsCollection.Beijing.CU169)
f.tracert(TestIPsCollection.Beijing.Location, TestIPsCollection.Beijing.CM)
f.tracert(TestIPsCollection.Beijing.Location, TestIPsCollection.Beijing.EDU)
}

View File

@@ -1,36 +1,30 @@
package fastTrace
import (
"fmt"
"os"
"os/signal"
"testing"
"github.com/xgadget-lab/nexttrace/trace"
"github.com/xgadget-lab/nexttrace/wshandle"
)
func TestTrace(t *testing.T) {
pFastTrace := ParamsFastTrace{
SrcDev: "",
SrcAddr: "",
BeginHop: 1,
MaxHops: 30,
RDns: false,
AlwaysWaitRDNS: false,
Lang: "",
PktSize: 52,
}
ft := FastTracer{ParamsFastTrace: pFastTrace}
// 建立 WebSocket 连接
w := wshandle.New()
w.Interrupt = make(chan os.Signal, 1)
signal.Notify(w.Interrupt, os.Interrupt)
defer func() {
w.Conn.Close()
}()
fmt.Println("TCP v4")
ft.TracerouteMethod = trace.TCPTrace
//pFastTrace := ParamsFastTrace{
// SrcDev: "",
// SrcAddr: "",
// BeginHop: 1,
// MaxHops: 30,
// RDns: false,
// AlwaysWaitRDNS: false,
// Lang: "",
// PktSize: 52,
//}
//ft := FastTracer{ParamsFastTrace: pFastTrace}
//// 建立 WebSocket 连接
//w := wshandle.New()
//w.Interrupt = make(chan os.Signal, 1)
//signal.Notify(w.Interrupt, os.Interrupt)
//defer func() {
// w.Conn.Close()
//}()
//fmt.Println("TCP v4")
//ft.TracerouteMethod = trace.TCPTrace
//ft.tracert(TestIPsCollection.Beijing.Location, TestIPsCollection.Beijing.EDU)
//fmt.Println("TCP v6")
//ft.tracert_v6(TestIPsCollection.Beijing.Location, TestIPsCollection.Beijing.EDU)

38
go.mod
View File

@@ -1,46 +1,50 @@
module github.com/xgadget-lab/nexttrace
module github.com/nxtrace/NTrace-core
go 1.20
go 1.21
require (
github.com/akamensky/argparse v1.4.0
github.com/google/gopacket v1.1.19
github.com/oschwald/maxminddb-golang v1.10.0
github.com/spf13/viper v1.16.0
github.com/oschwald/maxminddb-golang v1.12.0
github.com/spf13/viper v1.17.0
github.com/stretchr/testify v1.8.4
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635
github.com/tsosunchia/powclient v0.1.1
golang.org/x/net v0.10.0
golang.org/x/sync v0.2.0
github.com/tsosunchia/powclient v0.1.4
golang.org/x/net v0.17.0
golang.org/x/sync v0.4.0
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/afero v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/sagikazarmark/locafero v0.3.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.10.0 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
golang.org/x/text v0.9.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
golang.org/x/text v0.13.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
)
require (
github.com/fatih/color v1.15.0
github.com/gorilla/websocket v1.5.0
github.com/lionsoul2014/ip2region v2.11.1+incompatible
github.com/lionsoul2014/ip2region v2.11.2+incompatible
github.com/rodaine/table v1.1.0
github.com/tidwall/gjson v1.14.4
github.com/tidwall/gjson v1.17.0
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/sys v0.13.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

75
go.sum
View File

@@ -49,8 +49,9 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
@@ -60,6 +61,7 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
@@ -137,11 +139,13 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/lionsoul2014/ip2region v2.11.1+incompatible h1:FEqj5PvIP6YwnGt3RYndGQaiftEIJJGpw4BCB76nvfM=
github.com/lionsoul2014/ip2region v2.11.1+incompatible/go.mod h1:+ZBN7PBoh5gG6/y0ZQ85vJDBe21WnfbRrQQwTfliJJI=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lionsoul2014/ip2region v2.11.2+incompatible h1:+VRsGcrHz8ewXI/2UzTptJlACsxD/p4xCxuql4u2nKU=
github.com/lionsoul2014/ip2region v2.11.2+incompatible/go.mod h1:+ZBN7PBoh5gG6/y0ZQ85vJDBe21WnfbRrQQwTfliJJI=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
@@ -153,55 +157,59 @@ github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/Qd
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/oschwald/maxminddb-golang v1.10.0 h1:Xp1u0ZhqkSuopaKmk1WwHtjF0H9Hd9181uj2MQ5Vndg=
github.com/oschwald/maxminddb-golang v1.10.0/go.mod h1:Y2ELenReaLAZ0b400URyGwvYxHV1dLIxBuyOsyYjHK0=
github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
github.com/oschwald/maxminddb-golang v1.12.0 h1:9FnTOD0YOhP7DGxGsq4glzpGy5+w7pq50AS6wALUMYs=
github.com/oschwald/maxminddb-golang v1.12.0/go.mod h1:q0Nob5lTCqyQ8WT6FYgS1L7PXKVVbgiymefNwIjPzgY=
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rodaine/table v1.1.0 h1:/fUlCSdjamMY8VifdQRIu3VWZXYLY7QHFkVorS8NTr4=
github.com/rodaine/table v1.1.0/go.mod h1:Qu3q5wi1jTQD6B6HsP6szie/S4w1QUQ8pq22pz9iL8g=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=
github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/sagikazarmark/locafero v0.3.0 h1:zT7VEGWC2DTflmccN/5T1etyKvxSxpHsjb9cJvm4SvQ=
github.com/sagikazarmark/locafero v0.3.0/go.mod h1:w+v7UsPNFwzF1cHuOajOOzoq4U7v/ig1mpRjqV+Bu1U=
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY=
github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=
github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc=
github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg=
github.com/spf13/viper v1.17.0 h1:I5txKw7MJasPL/BrfkbA0Jyo/oELqVmux4pR/UxOMfI=
github.com/spf13/viper v1.17.0/go.mod h1:BmMMMLQXSbcHK6KAOiFLz0l5JHrU89OdIRHvsk0+yVI=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM=
github.com/tidwall/gjson v1.17.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tsosunchia/powclient v0.1.1 h1:Llv7vFNXTvpxrd2JjnAkpGz95gjVu6A2891RQCML3Rc=
github.com/tsosunchia/powclient v0.1.1/go.mod h1:Pm4MP3QqN74SfNskPpFIEyT+NQrcABGoXkkeRwjlMEE=
github.com/tsosunchia/powclient v0.1.4 h1:iAXUOiGPLJJTnzVSD0PY+4kBWm+SEMQZzd5ntEk1t0c=
github.com/tsosunchia/powclient v0.1.4/go.mod h1:Pm4MP3QqN74SfNskPpFIEyT+NQrcABGoXkkeRwjlMEE=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -212,6 +220,8 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -229,6 +239,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -284,8 +296,8 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -305,8 +317,8 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -345,8 +357,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -356,8 +368,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -501,8 +513,9 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=

View File

@@ -2,7 +2,7 @@ package ipgeo
import (
"encoding/json"
"github.com/xgadget-lab/nexttrace/util"
"github.com/nxtrace/NTrace-core/util"
"io"
"log"
"net/http"

View File

@@ -4,7 +4,7 @@ import (
"strings"
"time"
"github.com/xgadget-lab/nexttrace/dn42"
"github.com/nxtrace/NTrace-core/dn42"
)
func LtdCodeToCountryOrAreaName(Code string) string {

View File

@@ -23,14 +23,24 @@ func downloadDataBase() error {
if err != nil {
return err
}
defer resp.Body.Close()
defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
panic(err)
}
}(resp.Body)
// Create the file
out, err := os.Create(ipDataBasePath)
if err != nil {
return err
}
defer out.Close()
defer func(out *os.File) {
err := out.Close()
if err != nil {
panic(err)
}
}(out)
// Write the body to file
_, err = io.Copy(out, resp.Body)

View File

@@ -2,17 +2,19 @@ package ipgeo
import (
"errors"
"github.com/nxtrace/NTrace-core/util"
"io"
"log"
"net/http"
"regexp"
"strconv"
"time"
"github.com/tidwall/gjson"
)
func IPApiCom(ip string, timeout time.Duration, _ string, _ bool) (*IPGeoData, error) {
url := "http://ip-api.com/json/" + ip + "?fields=status,message,country,regionName,city,isp,as"
url := "http://ip-api.com/json/" + ip + "?fields=status,message,country,regionName,city,isp,district,as,lat,lon"
client := &http.Client{
// 2 秒超时
Timeout: timeout,
@@ -32,12 +34,27 @@ func IPApiCom(ip string, timeout time.Duration, _ string, _ bool) (*IPGeoData, e
}
re := regexp.MustCompile("[0-9]+")
var country = res.Get("country").String()
var prov = res.Get("region").String()
var city = res.Get("city").String()
var district = res.Get("district").String()
if util.StringInSlice(country, []string{"Hong Kong", "Taiwan", "Macao"}) {
district = prov + " " + city + " " + district
city = country
prov = ""
country = "China"
}
lat, _ := strconv.ParseFloat(res.Get("lat").String(), 32)
lng, _ := strconv.ParseFloat(res.Get("lon").String(), 32)
return &IPGeoData{
Asnumber: re.FindString(res.Get("as").String()),
Country: res.Get("country").String(),
City: res.Get("city").String(),
Prov: res.Get("regionName").String(),
Country: country,
City: city,
Prov: prov,
District: district,
Owner: res.Get("isp").String(),
Lat: lat,
Lng: lng,
}, nil
}

View File

@@ -20,16 +20,40 @@ func Filter(ip string) (*IPGeoData, bool) {
whois := ""
isFiltered := false
switch {
//rfc1918
case net.ParseIP(ip).IsPrivate():
case cidrRangeContains("0.0.0.0/8", ip):
asn = ""
whois = "RFC1918"
whois = "RFC1122"
isFiltered = true
//IANA Reserved Address Space
case cidrRangeContains("100.64.0.0/10", ip):
asn = ""
whois = "RFC6598"
isFiltered = true
//127.0.0.0/8
case cidrRangeContains("127.0.0.0/8", ip):
asn = ""
whois = "RFC1122"
isFiltered = true
//169.254.0.0/16
case cidrRangeContains("169.254.0.0/16", ip):
asn = ""
whois = "RFC3927"
isFiltered = true
//192.0.0.0/24
case cidrRangeContains("192.0.0.0/24", ip):
asn = ""
whois = "RFC6890"
isFiltered = true
//192.0.2.0/24
case cidrRangeContains("192.0.2.0/24", ip):
asn = ""
whois = "RFC5737"
isFiltered = true
//192.88.99.0/24
case cidrRangeContains("192.88.99.0/24", ip):
asn = ""
whois = "RFC3068"
isFiltered = true
case cidrRangeContains("198.18.0.0/15", ip):
asn = ""
whois = "RFC2544"
@@ -40,10 +64,68 @@ func Filter(ip string) (*IPGeoData, bool) {
asn = ""
whois = "RFC5737"
isFiltered = true
//224.0.0.0/4
case cidrRangeContains("224.0.0.0/4", ip):
asn = ""
whois = "RFC5771"
isFiltered = true
//255.255.255.255/32
case cidrRangeContains("255.255.255.255/32", ip):
asn = ""
whois = "RFC0919"
isFiltered = true
case cidrRangeContains("240.0.0.0/4", ip):
asn = ""
whois = "RFC1112"
isFiltered = true
case cidrRangeContains("fe80::/10", ip):
asn = ""
whois = "RFC4291"
isFiltered = true
case cidrRangeContains("ff00::/8", ip):
asn = ""
whois = "RFC4291"
isFiltered = true
case cidrRangeContains("fec0::/10", ip):
asn = ""
whois = "RFC3879"
isFiltered = true
case cidrRangeContains("fe00::/9", ip):
asn = ""
whois = "RFC4291"
isFiltered = true
case cidrRangeContains("64:ff9b::/96", ip):
asn = ""
whois = "RFC6052"
isFiltered = true
case cidrRangeContains("0::/96", ip):
asn = ""
whois = "RFC4291"
isFiltered = true
case cidrRangeContains("64:ff9b:1::/48", ip):
asn = ""
whois = "RFC6052"
isFiltered = true
case cidrRangeContains("2001:db8::/32", ip):
asn = ""
whois = "RFC3849"
isFiltered = true
case cidrRangeContains("2002::/16", ip):
asn = ""
whois = "RFC3056"
isFiltered = true
case net.ParseIP(ip).IsPrivate():
//rfc4193
if cidrRangeContains("fc00::/7", ip) {
asn = ""
whois = "RFC4193"
isFiltered = true
//rfc1918
} else {
asn = ""
whois = "RFC1918"
isFiltered = true
}
//Defense Information System Network
case cidrRangeContains("6.0.0.0/8", ip):
fallthrough
@@ -75,6 +157,12 @@ func Filter(ip string) (*IPGeoData, bool) {
isFiltered = true
default:
}
// 判断是否为v6 且不在2000::/3
if net.ParseIP(ip).To4() == nil && !cidrRangeContains("2000::/3", ip) && !isFiltered {
asn = ""
whois = "INVALID"
isFiltered = true
}
if !isFiltered {
return nil, false
} else {

View File

@@ -37,6 +37,13 @@ func TestXxx(t *testing.T) {
log.Println(process_id, ttl_r)
}
func TestFilter(t *testing.T) {
res, err := Filter("fd11::1")
//打印whois信息
fmt.Println(res.Whois)
print(err)
}
func reverseID(id string) (int64, int64, error) {
ttl, _ := strconv.ParseInt(id[9:15], 2, 32)
//process ID

View File

@@ -1,8 +1,10 @@
package ipgeo
import (
"github.com/nxtrace/NTrace-core/util"
"io"
"net/http"
"strconv"
"strings"
"time"
@@ -10,7 +12,7 @@ import (
)
func IPInfo(ip string, timeout time.Duration, _ string, _ bool) (*IPGeoData, error) {
url := "https://ipinfo.io/" + ip + "?token=" + token.ipinfo
url := "http://ipinfo.io/" + ip + "?token=" + token.ipinfo
client := &http.Client{
// 2 秒超时
Timeout: timeout,
@@ -28,11 +30,6 @@ func IPInfo(ip string, timeout time.Duration, _ string, _ bool) (*IPGeoData, err
res := gjson.ParseBytes(body)
var country string
country = res.Get("country").String()
if res.Get("country").String() == "HK" || res.Get("country").String() == "TW" {
country = "CN"
}
// ISO-3166 转换
var countryMap = map[string]string{
"AF": "Afghanistan",
@@ -285,7 +282,26 @@ func IPInfo(ip string, timeout time.Duration, _ string, _ bool) (*IPGeoData, err
"ZM": "Zambia",
"ZW": "Zimbabwe",
}
var country = res.Get("country").String()
var prov = res.Get("region").String()
var city = res.Get("city").String()
var district = ""
if util.StringInSlice(country, []string{"TW", "MO", "HK"}) {
district = prov + " " + city
city = countryMap[country]
prov = ""
country = "CN"
}
country = countryMap[country]
var anycast = false
if res.Get("anycast").String() == "true" {
country = "ANYCAST"
prov = "ANYCAST"
city = ""
anycast = true
}
i := strings.Index(res.Get("org").String(), " ")
var owner string
if i == -1 {
@@ -300,11 +316,24 @@ func IPInfo(ip string, timeout time.Duration, _ string, _ bool) (*IPGeoData, err
asnumber = strings.Fields(strings.TrimPrefix(res.Get("org").String(), "AS"))[0]
}
//"loc": "34.0522,-118.2437",
var lat, lng float64
if res.Get("loc").String() != "" {
lat, _ = strconv.ParseFloat(strings.Split(res.Get("loc").String(), ",")[0], 32)
lng, _ = strconv.ParseFloat(strings.Split(res.Get("loc").String(), ",")[1], 32)
}
if anycast {
lat, lng = 0, 0
}
return &IPGeoData{
Asnumber: asnumber,
Country: country,
City: res.Get("city").String(),
Prov: res.Get("region").String(),
City: city,
Prov: prov,
District: district,
Owner: owner,
Lat: lat,
Lng: lng,
}, nil
}

View File

@@ -7,8 +7,8 @@ import (
"sync"
"time"
"github.com/nxtrace/NTrace-core/wshandle"
"github.com/tidwall/gjson"
"github.com/xgadget-lab/nexttrace/wshandle"
)
/***

View File

@@ -1,6 +1,6 @@
package ipgeo
import "github.com/xgadget-lab/nexttrace/util"
import "github.com/nxtrace/NTrace-core/util"
type tokenData struct {
ipinsight string

View File

@@ -1,7 +1,7 @@
package main
import (
"github.com/xgadget-lab/nexttrace/cmd"
"github.com/nxtrace/NTrace-core/cmd"
)
func main() {

View File

@@ -93,12 +93,7 @@ checkWgetPackage() {
downloadBinrayFile() {
echo -e "${Info} 获取最新版的 NextTrace 发行版文件信息"
# 简单说明一下Github提供了一个API可以获取最新发行版本的二进制文件下载地址对应的是browser_download_url根据刚刚测得的osDistribution、archParam获取对应的下载地址
latestURL=$(curl -s https://api.github.com/repos/sjlleo/nexttrace/releases/latest | grep -i "browser_download_url.*${osDistribution}.*${archParam}" | awk -F '"' '{print $4}')
if [ "$countryCode" == "CN" ]; then
echo -e "${Info} 检测到国内环境,正在使用镜像下载"
latestURL="https://ghproxy.com/"$latestURL
fi
latestURL=$(curl -sL http://nexttrace-io-leomoe-api-a0.shop/latest_v1.json | grep -i "browser_download_url.*${osDistribution}.*${archParam}" | awk -F '"' '{print $4}')
echo -e "${Info} 正在下载 NextTrace 二进制文件..."
wget -O ${Temp_path} ${latestURL} &> /dev/null
@@ -130,8 +125,6 @@ checkSystemDistribution
checkSystemArch
checkWgetPackage
# Download Procedure
getLocation
downloadBinrayFile
# Run Procedure

View File

@@ -2,8 +2,8 @@ package pow
import (
"fmt"
"github.com/nxtrace/NTrace-core/util"
"github.com/tsosunchia/powclient"
"github.com/xgadget-lab/nexttrace/util"
"net/url"
"os"
)
@@ -19,10 +19,17 @@ func GetToken(fastIp string, host string, port string) (string, error) {
getTokenParams.SNI = host
getTokenParams.Host = host
getTokenParams.UserAgent = util.UserAgent
var err error
proxyUrl := util.GetProxy()
if proxyUrl != nil {
getTokenParams.Proxy = proxyUrl
}
var (
token string
err error
)
// 尝试三次RetToken如果都失败了异常退出
for i := 0; i < 3; i++ {
token, err := powclient.RetToken(getTokenParams)
token, err = powclient.RetToken(getTokenParams)
if err != nil {
continue
}
@@ -32,7 +39,7 @@ func GetToken(fastIp string, host string, port string) (string, error) {
if err != nil {
fmt.Println(err)
}
fmt.Println("RetToken failed 3 times, exit")
fmt.Println("RetToken failed 3 times, please try again after a while, exit")
os.Exit(1)
return "", nil
return "", err
}

View File

@@ -10,7 +10,7 @@ import (
func TestGetToken(t *testing.T) {
// 计时开始
start := time.Now()
token, err := GetToken("103.120.18.35", "api.leo.moe", "443")
token, err := GetToken("api.leo.moe", "api.leo.moe", "443")
// 计时结束
end := time.Now()
fmt.Println("耗时:", end.Sub(start))

View File

@@ -2,8 +2,8 @@ package printer
import (
"fmt"
"github.com/xgadget-lab/nexttrace/config"
"github.com/xgadget-lab/nexttrace/trace"
"github.com/nxtrace/NTrace-core/config"
"github.com/nxtrace/NTrace-core/trace"
"net"
"github.com/fatih/color"
@@ -41,13 +41,14 @@ func CopyRight() {
color.New(color.FgHiBlack, color.Bold).Sprintf("%s", "zhshch@athorx.com"),
)
MoeQingOrgCopyRight()
PluginCopyRight()
moeQingOrgCopyRight()
sponsor()
//PluginCopyRight()
}
func MoeQingOrgCopyRight() {
func moeQingOrgCopyRight() {
fmt.Fprintf(color.Output, "%s\n%s %s\n%s %s\n\n",
color.New(color.FgHiYellow, color.Bold).Sprintf("%s", "MoeQing Network"),
color.New(color.FgGreen, color.Bold).Sprintf("%s", "Supported by MoeQing Network"),
color.New(color.FgWhite, color.Bold).Sprintf("%s", "YekongTAT"),
color.New(color.FgHiBlack, color.Bold).Sprintf("%s", "yekongtat@gmail.com"),
color.New(color.FgWhite, color.Bold).Sprintf("%s", "Haima"),
@@ -55,14 +56,23 @@ func MoeQingOrgCopyRight() {
)
}
func PluginCopyRight() {
fmt.Fprintf(color.Output, "%s\n%s %s\n\n",
color.New(color.FgGreen, color.Bold).Sprintf("%s", "NextTrace Map Plugin Author"),
color.New(color.FgWhite, color.Bold).Sprintf("%s", "Tso"),
color.New(color.FgHiBlack, color.Bold).Sprintf("%s", "tsosunchia@gmail.com"),
func sponsor() {
fmt.Fprintf(color.Output, "%s\n%s\n%s\n%s\n",
color.New(color.FgGreen, color.Bold).Sprintf("%s", "Sponsored by the following entities"),
color.New(color.FgWhite, color.Bold).Sprintf("%s", "DMIT.io"),
color.New(color.FgWhite, color.Bold).Sprintf("%s", "Misaka.io"),
color.New(color.FgWhite, color.Bold).Sprintf("%s", "Skywolf.cloud"),
)
}
//func PluginCopyRight() {
// fmt.Fprintf(color.Output, "%s\n%s %s\n\n",
// color.New(color.FgGreen, color.Bold).Sprintf("%s", "NextTrace Map Plugin Author"),
// color.New(color.FgWhite, color.Bold).Sprintf("%s", "Tso"),
// color.New(color.FgHiBlack, color.Bold).Sprintf("%s", "tsosunchia@gmail.com"),
// )
//}
func PrintTraceRouteNav(ip net.IP, domain string, dataOrigin string, maxHops int, packetSize int) {
fmt.Println("IP Geo Data Provider: " + dataOrigin)
@@ -75,8 +85,18 @@ func PrintTraceRouteNav(ip net.IP, domain string, dataOrigin string, maxHops int
func applyLangSetting(h *trace.Hop) {
if len(h.Geo.Country) <= 1 {
h.Geo.Country = "局域网"
h.Geo.CountryEn = "LAN Address"
//打印h.geo
if h.Geo.Whois != "" {
h.Geo.Country = h.Geo.Whois
} else {
if h.Geo.Source != "LeoMoeAPI" {
h.Geo.Country = "网络故障"
h.Geo.CountryEn = "Network Error"
} else {
h.Geo.Country = "未知"
h.Geo.CountryEn = "Unknown"
}
}
}
if h.Lang == "en" {
@@ -98,4 +118,5 @@ func applyLangSetting(h *trace.Hop) {
}
}
}
}

View File

@@ -4,7 +4,7 @@ import (
"fmt"
"strings"
"github.com/xgadget-lab/nexttrace/trace"
"github.com/nxtrace/NTrace-core/trace"
)
type HopInfo int

View File

@@ -3,7 +3,7 @@ package printer
import (
"fmt"
"github.com/xgadget-lab/nexttrace/trace"
"github.com/nxtrace/NTrace-core/trace"
)
func EasyPrinter(res *trace.Result, ttl int) {

View File

@@ -4,9 +4,9 @@ import (
"fmt"
"strings"
"github.com/xgadget-lab/nexttrace/trace"
"github.com/nxtrace/NTrace-core/trace"
"github.com/xgadget-lab/nexttrace/ipgeo"
"github.com/nxtrace/NTrace-core/ipgeo"
)
// var dataOrigin string
@@ -47,6 +47,9 @@ func HopPrinter(h trace.Hop, info HopInfo) {
if h.Geo != nil {
txt += " " + formatIpGeoData(h.Address.String(), h.Geo)
}
for _, v := range h.MPLS {
txt += " " + v
}
switch info {
case IXP:
fmt.Print(CYAN_PREFIX)

View File

@@ -7,7 +7,7 @@ import (
"strings"
"github.com/fatih/color"
"github.com/xgadget-lab/nexttrace/trace"
"github.com/nxtrace/NTrace-core/trace"
)
func RealtimePrinter(res *trace.Result, ttl int) {
@@ -98,7 +98,13 @@ func RealtimePrinter(res *trace.Result, ttl int) {
}
if whoisFormat[0] != "" {
whoisFormat[0] = "[" + whoisFormat[0] + "]"
//如果以RFC或DOD开头那么为空
if !(strings.HasPrefix(whoisFormat[0], "RFC") ||
strings.HasPrefix(whoisFormat[0], "DOD")) {
whoisFormat[0] = "[" + whoisFormat[0] + "]"
} else {
whoisFormat[0] = ""
}
}
// CMIN2, CUII, CN2, CUG 改为壕金色高亮
@@ -160,6 +166,11 @@ func RealtimePrinter(res *trace.Result, ttl int) {
)
}
}
for _, v := range res.Hops[ttl][i].MPLS {
fmt.Fprintf(color.Output, "%s",
color.New(color.FgHiBlack, color.Bold).Sprintf("\n %s", v),
)
}
fmt.Println()
blockDisplay = true
}

View File

@@ -7,7 +7,7 @@ import (
"strings"
"github.com/fatih/color"
"github.com/xgadget-lab/nexttrace/trace"
"github.com/nxtrace/NTrace-core/trace"
)
func RealtimePrinterWithRouter(res *trace.Result, ttl int) {

View File

@@ -4,9 +4,9 @@ import (
"fmt"
"strings"
"github.com/xgadget-lab/nexttrace/ipgeo"
"github.com/nxtrace/NTrace-core/ipgeo"
"github.com/xgadget-lab/nexttrace/trace"
"github.com/nxtrace/NTrace-core/trace"
"github.com/fatih/color"
"github.com/rodaine/table"

View File

@@ -6,8 +6,8 @@ import (
"strings"
"sync"
"github.com/xgadget-lab/nexttrace/ipgeo"
"github.com/xgadget-lab/nexttrace/trace"
"github.com/nxtrace/NTrace-core/ipgeo"
"github.com/nxtrace/NTrace-core/trace"
)
type Reporter interface {

View File

@@ -5,8 +5,8 @@ import (
"testing"
"time"
"github.com/xgadget-lab/nexttrace/ipgeo"
"github.com/xgadget-lab/nexttrace/trace"
"github.com/nxtrace/NTrace-core/ipgeo"
"github.com/nxtrace/NTrace-core/trace"
)
var testResult = &trace.Result{

View File

@@ -12,7 +12,6 @@ import (
"sync"
"time"
"github.com/xgadget-lab/nexttrace/trace/internal"
"golang.org/x/net/context"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv4"
@@ -31,6 +30,8 @@ type ICMPTracer struct {
fetchLock sync.Mutex
}
var psize = 52
func (t *ICMPTracer) PrintFunc() {
defer t.wg.Done()
var ttl = t.Config.BeginHop - 1
@@ -65,7 +66,7 @@ func (t *ICMPTracer) Execute() (*Result, error) {
var err error
t.icmpListen, err = internal.ListenICMP("ip4:1", t.SrcAddr)
t.icmpListen, err = net.ListenPacket("ip4:1", t.SrcAddr)
if err != nil {
return &t.res, err
}
@@ -119,6 +120,7 @@ func (t *ICMPTracer) Execute() (*Result, error) {
func (t *ICMPTracer) listenICMP() {
lc := NewPacketListener(t.icmpListen, t.ctx)
psize = t.Config.PktSize
go lc.Start()
for {
select {
@@ -176,10 +178,13 @@ func (t *ICMPTracer) listenICMP() {
func (t *ICMPTracer) handleICMPMessage(msg ReceivedMessage, icmpType int8, data []byte, ttl int) {
t.inflightRequestRWLock.RLock()
defer t.inflightRequestRWLock.RUnlock()
mpls := extractMPLS(msg, data)
if _, ok := t.inflightRequest[ttl]; ok {
t.inflightRequest[ttl] <- Hop{
Success: true,
Address: msg.Peer,
MPLS: mpls,
}
}
}
@@ -202,7 +207,7 @@ func gernerateID(ttl_int int) int {
id += "0"
}
res, _ := strconv.ParseInt(id, 2, 64)
res, _ := strconv.ParseInt(id, 2, 32)
return int(res)
}
@@ -257,7 +262,7 @@ func (t *ICMPTracer) send(ttl int) error {
Body: &icmp.Echo{
ID: id,
//Data: []byte("HELLO-R-U-THERE"),
Data: bytes.Repeat([]byte{1}, t.Config.PktSize),
Data: append(bytes.Repeat([]byte{1}, t.Config.PktSize-4), 0x00, 0x00, 0x4f, 0xff),
Seq: ttl,
},
}

View File

@@ -10,7 +10,6 @@ import (
"sync"
"time"
"github.com/xgadget-lab/nexttrace/trace/internal"
"golang.org/x/net/context"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv6"
@@ -66,7 +65,7 @@ func (t *ICMPTracerv6) Execute() (*Result, error) {
var err error
t.icmpListen, err = internal.ListenICMP("ip6:58", t.SrcAddr)
t.icmpListen, err = net.ListenPacket("ip6:58", t.SrcAddr)
if err != nil {
return &t.res, err
}
@@ -138,6 +137,7 @@ func (t *ICMPTracerv6) Execute() (*Result, error) {
func (t *ICMPTracerv6) listenICMP() {
lc := NewPacketListener(t.icmpListen, t.ctx)
psize = t.Config.PktSize
go lc.Start()
for {
select {
@@ -234,10 +234,13 @@ func (t *ICMPTracerv6) listenICMP() {
func (t *ICMPTracerv6) handleICMPMessage(msg ReceivedMessage, icmpType int8, data []byte, ttl int) {
t.inflightRequestRWLock.RLock()
defer t.inflightRequestRWLock.RUnlock()
mpls := extractMPLS(msg, data)
if _, ok := t.inflightRequest[ttl]; ok {
t.inflightRequest[ttl] <- Hop{
Success: true,
Address: msg.Peer,
MPLS: mpls,
}
}
}
@@ -254,7 +257,7 @@ func (t *ICMPTracerv6) send(ttl int) error {
Body: &icmp.Echo{
ID: id,
//Data: []byte("HELLO-R-U-THERE"),
Data: bytes.Repeat([]byte{1}, t.Config.PktSize),
Data: append(bytes.Repeat([]byte{1}, t.Config.PktSize-4), 0x00, 0x00, 0x4f, 0xff),
Seq: ttl,
},
}

View File

@@ -28,6 +28,7 @@ var (
}
)
// ListenICMP 会造成指定出口IP功能不可使用
func ListenICMP(network string, laddr string) (net.PacketConn, error) {
if os.Getuid() == 0 { // root
return net.ListenPacket(network, laddr)

View File

@@ -10,7 +10,7 @@ import (
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/xgadget-lab/nexttrace/util"
"github.com/nxtrace/NTrace-core/util"
"golang.org/x/net/context"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv4"
@@ -257,7 +257,7 @@ func (t *TCPTracer) send(ttl int) error {
t.inflightRequest[int(sequenceNumber)] = hopCh
t.inflightRequestLock.Unlock()
/*
// 这里属于 2个SenderN个Reciever的情况在哪里关闭Channel都容易导致Panic
// 这里属于 2个SenderN个Receiver的情况在哪里关闭Channel都容易导致Panic
defer func() {
t.inflightRequestLock.Lock()
close(hopCh)

View File

@@ -10,7 +10,7 @@ import (
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/xgadget-lab/nexttrace/util"
"github.com/nxtrace/NTrace-core/util"
"golang.org/x/net/context"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv6"

View File

@@ -4,7 +4,7 @@ import (
"fmt"
"strings"
"github.com/xgadget-lab/nexttrace/ipgeo"
"github.com/nxtrace/NTrace-core/ipgeo"
)
func HopPrinter(h Hop) {

View File

@@ -2,12 +2,15 @@ package trace
import (
"errors"
"fmt"
"net"
"strconv"
"strings"
"sync"
"time"
"github.com/xgadget-lab/nexttrace/ipgeo"
"github.com/xgadget-lab/nexttrace/util"
"github.com/nxtrace/NTrace-core/ipgeo"
"github.com/nxtrace/NTrace-core/util"
)
var (
@@ -124,6 +127,7 @@ type Hop struct {
Error error
Geo *ipgeo.IPGeoData
Lang string
MPLS []string
}
func (h *Hop) fetchIPData(c Config) (err error) {
@@ -137,7 +141,7 @@ func (h *Hop) fetchIPData(c Config) (err error) {
h.Hostname = r[0][:len(r[0])-1]
ip = h.Address.String() + "," + h.Hostname
}
h.Geo, err = c.IPGeoSource(ip, c.Timeout, c.Lang, c.Maptrace)
h.Geo, _ = c.IPGeoSource(ip, c.Timeout, c.Lang, c.Maptrace)
return nil
}
@@ -217,11 +221,116 @@ func (h *Hop) fetchIPData(c Config) (err error) {
selectClose = true
}
// When Select Close, fetchDoneChan Reciever will also be closed
// When Select Close, fetchDoneChan Received will also be closed
if selectClose {
// New a reciever to prevent channel congestion
// New a receiver to prevent channel congestion
<-fetchDoneChan
}
return
}
func extractMPLS(msg ReceivedMessage, data []byte) []string {
if util.DisableMPLS != "" {
return nil
}
if psize != 52 {
return nil
}
extensionOffset := 20 + 8 + psize
if len(data) <= extensionOffset {
return nil
}
extensionBody := data[extensionOffset:]
if len(extensionBody) < 8 || len(extensionBody)%8 != 0 {
return nil
}
tmp := fmt.Sprintf("%x", msg.Msg[:*msg.N])
index := strings.Index(tmp, strings.Repeat("01", psize-4)+"00004fff")
if index == -1 {
return nil
}
tmp = tmp[index+psize*2:]
//由于限制长度了
index1 := strings.Index(tmp, "00002000")
l := len(tmp[index1+4:])/8 - 2
//fmt.Printf("l:%d\n", l)
if l < 1 {
return nil
}
//去掉扩展头和MPLS头
tmp = tmp[index1+4+8*2:]
//fmt.Print(tmp)
var retStrList []string
for i := 0; i < l; i++ {
label, err := strconv.ParseInt(tmp[i*8+0:i*8+5], 16, 32)
if err != nil {
return nil
}
strSlice := fmt.Sprintf("%s", []byte(tmp[i*8+5:i*8+6]))
//fmt.Printf("\nstrSlice: %s\n", strSlice)
num, err := strconv.ParseUint(strSlice, 16, 64)
if err != nil {
return nil
}
binaryStr := fmt.Sprintf("%04s", strconv.FormatUint(num, 2))
//fmt.Printf("\nbinaryStr: %s\n", binaryStr)
tc, err := strconv.ParseInt(binaryStr[:3], 2, 32)
if err != nil {
return nil
}
s := binaryStr[3:]
ttlMpls, err := strconv.ParseInt(tmp[i*8+6:i*8+8], 16, 32)
if err != nil {
return nil
}
//if i > 0 {
// retStr += "\n "
//}
retStrList = append(retStrList, fmt.Sprintf("[MPLS: Lbl %d, TC %d, S %s, TTL %d]", label, tc, s, ttlMpls))
}
//label, err := strconv.ParseInt(tmp[len(tmp)-8:len(tmp)-3], 16, 32)
//if err != nil {
// return ""
//}
//
//strSlice := fmt.Sprintf("%s", []byte(tmp[len(tmp)-3:len(tmp)-2]))
////fmt.Printf("\nstrSlice: %s\n", strSlice)
//
//num, err := strconv.ParseUint(strSlice, 16, 64)
//if err != nil {
// return ""
//}
//binaryStr := fmt.Sprintf("%04s", strconv.FormatUint(num, 2))
//
////fmt.Printf("\nbinaryStr: %s\n", binaryStr)
//tc, err := strconv.ParseInt(binaryStr[:3], 2, 32)
//if err != nil {
// return ""
//}
//s := binaryStr[3:]
//
//ttlMpls, err := strconv.ParseInt(tmp[len(tmp)-2:], 16, 32)
//if err != nil {
// return ""
//}
//
//retStr := fmt.Sprintf("Lbl %d, TC %d, S %s, TTL %d", label, tc, s, ttlMpls)
return retStrList
}

View File

@@ -8,7 +8,7 @@ import (
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/xgadget-lab/nexttrace/util"
"github.com/nxtrace/NTrace-core/util"
"golang.org/x/net/context"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv4"

View File

@@ -9,7 +9,7 @@ import (
"strconv"
"strings"
"github.com/xgadget-lab/nexttrace/trace"
"github.com/nxtrace/NTrace-core/trace"
)
func RealtimePrinter(res *trace.Result, ttl int) {

View File

@@ -5,7 +5,7 @@ import (
"errors"
"fmt"
"github.com/fatih/color"
"github.com/xgadget-lab/nexttrace/util"
"github.com/nxtrace/NTrace-core/util"
"io"
"net"
"net/http"
@@ -35,6 +35,10 @@ func GetMapUrl(r string) (string, error) {
},
},
}
proxyUrl := util.GetProxy()
if proxyUrl != nil {
client.Transport.(*http.Transport).Proxy = http.ProxyURL(proxyUrl)
}
req, err := http.NewRequest("POST", tracemapUrl, strings.NewReader(r))
if err != nil {
return "", errors.New("an issue occurred while connecting to the tracemap API")
@@ -62,7 +66,7 @@ func GetMapUrl(r string) (string, error) {
func PrintMapUrl(r string) {
_, err := fmt.Fprintf(color.Output, "%s %s\n",
color.New(color.FgWhite, color.Bold).Sprintf("%s", "MapTrace URL:"),
color.New(color.FgBlue, color.Bold).Sprintf("%s", string(r)),
color.New(color.FgBlue, color.Bold).Sprintf("%s", r),
)
if err != nil {
return

View File

@@ -13,8 +13,8 @@ func TestDNS(t *testing.T) {
}
func TestDomainLookUp(t *testing.T) {
ips := DomainLookUp("pek-4134.nexttrace-io-fasttrace-endpoint.win.", "all", "", false)
ips, _ := DomainLookUp("pek-4134.nexttrace-io-fasttrace-endpoint.win.", "all", "", false)
fmt.Println(ips)
ips = DomainLookUp("pek-4134.nexttrace-io-fasttrace-endpoint.win.", "4", "", false)
ips, _ = DomainLookUp("pek-4134.nexttrace-io-fasttrace-endpoint.win.", "4", "", false)
fmt.Println(ips)
}

View File

@@ -1,22 +1,35 @@
package util
import (
"crypto/tls"
"fmt"
"io"
"log"
"net"
"net/http"
"strings"
"time"
"github.com/fatih/color"
)
type ResponseInfo struct {
IP string
Latency string
Content string
}
var (
result string
results = make(chan string)
results = make(chan ResponseInfo)
timeout = 5 * time.Second
)
var FastIpCache = ""
func GetFastIP(domain string, port string, enableOutput bool) string {
proxyUrl := GetProxy()
if proxyUrl != nil {
return "api.leo.moe"
}
if FastIpCache != "" {
return FastIpCache
}
@@ -26,50 +39,83 @@ func GetFastIP(domain string, port string, enableOutput bool) string {
log.Fatal("DNS resolution failed, please check your system DNS Settings")
}
for _, ip := range ips {
go checkLatency(ip.String(), port)
if len(ips) == 0 {
// 添加默认IP 45.88.195.154
ips = append(ips, net.ParseIP("45.88.195.154"))
}
for _, ip := range ips {
go checkLatency(domain, ip.String(), port)
}
var result ResponseInfo
select {
case result = <-results:
case <-time.After(1 * time.Second):
}
if result == "" {
log.Fatal("IP connection has been timeout, please check your network")
}
res := strings.Split(result, "-")
//等待5s没有结果 视为连不上API了
case <-time.After(timeout):
log.Println("IP connection has been timeout, please check your network")
if len(ips) > 1 {
if enableOutput {
_, _ = fmt.Fprintf(color.Output, "%s prefered API IP - %s - %s\n",
color.New(color.FgWhite, color.Bold).Sprintf("[NextTrace API]"),
color.New(color.FgGreen, color.Bold).Sprintf("%s", res[0]),
color.New(color.FgCyan, color.Bold).Sprintf("%sms", res[1]),
)
}
}
FastIpCache = res[0]
return res[0]
//if len(ips) > 0 {
if enableOutput {
_, _ = fmt.Fprintf(color.Output, "%s preferred API IP - %s - %s - %s",
color.New(color.FgWhite, color.Bold).Sprintf("[NextTrace API]"),
color.New(color.FgGreen, color.Bold).Sprintf("%s", result.IP),
color.New(color.FgCyan, color.Bold).Sprintf("%sms", result.Latency),
color.New(color.FgGreen, color.Bold).Sprintf("%s", result.Content),
)
}
//}
FastIpCache = result.IP
return result.IP
}
func checkLatency(ip string, port string) {
func checkLatency(domain string, ip string, port string) {
start := time.Now()
if !strings.Contains(ip, ".") {
ip = "[" + ip + "]"
}
conn, err := net.DialTimeout("tcp", ip+":"+port, time.Second*1)
// 自定义DialContext以使用指定的IP连接
transport := &http.Transport{
//DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
// return net.DialTimeout(network, addr, 1*time.Second)
//},
TLSClientConfig: &tls.Config{
ServerName: domain,
},
TLSHandshakeTimeout: timeout,
}
client := &http.Client{
Transport: transport,
Timeout: timeout,
}
//此处虽然是 https://domain/ 但是实际上会使用指定的IP连接
req, err := http.NewRequest("GET", "https://"+ip+":"+port+"/", nil)
if err != nil {
// !!! 此处不要给results返回任何值
//results <- ResponseInfo{IP: ip, Latency: "error", Content: ""}
return
}
defer func(conn net.Conn) {
err := conn.Close()
if err != nil {
return
}
}(conn)
if result == "" {
result = fmt.Sprintf("%s-%.2f", ip, float64(time.Since(start))/float64(time.Millisecond))
results <- result
req.Host = domain
resp, err := client.Do(req)
if err != nil {
//results <- ResponseInfo{IP: ip, Latency: "error", Content: ""}
return
}
defer resp.Body.Close()
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
//results <- ResponseInfo{IP: ip, Latency: "error", Content: ""}
return
}
bodyString := string(bodyBytes)
latency := fmt.Sprintf("%.2f", float64(time.Since(start))/float64(time.Millisecond))
results <- ResponseInfo{IP: ip, Latency: latency, Content: bodyString}
}

View File

@@ -1,9 +1,6 @@
package util
import (
"testing"
)
func TestGetFastIP(t *testing.T) {
GetFastIP("api.leo.moe", "443", true)
}
//github action test 不支持v6 这里会报错
//func TestGetFastIP(t *testing.T) {
// GetFastIP("api.leo.moe", "443", true)
//}

View File

@@ -2,10 +2,12 @@ package util
import (
"context"
"errors"
"fmt"
"github.com/xgadget-lab/nexttrace/config"
"github.com/nxtrace/NTrace-core/config"
"log"
"net"
"net/url"
"os"
"runtime"
"strings"
@@ -18,6 +20,8 @@ var Uninterrupted = GetenvDefault("NEXTTRACE_UNINTERRUPTED", "")
var EnvToken = GetenvDefault("NEXTTRACE_TOKEN", "")
var UserAgent = fmt.Sprintf("NextTrace %s/%s/%s", config.Version, runtime.GOOS, runtime.GOARCH)
var RdnsCache sync.Map
var PowProviderParam = ""
var DisableMPLS = GetenvDefault("NEXTTRACE_DISABLEMPLS", "")
func LookupAddr(addr string) ([]string, error) {
// 如果在缓存中找到,直接返回
@@ -72,7 +76,7 @@ func LocalIPPortv6(dstip net.IP) (net.IP, int) {
return nil, -1
}
func DomainLookUp(host string, ipVersion string, dotServer string, disableOutput bool) net.IP {
func DomainLookUp(host string, ipVersion string, dotServer string, disableOutput bool) (net.IP, error) {
// ipVersion: 4, 6, all
var (
r *net.Resolver
@@ -98,8 +102,7 @@ func DomainLookUp(host string, ipVersion string, dotServer string, disableOutput
ips = append(ips, net.ParseIP(v))
}
if err != nil {
fmt.Println("Domain " + host + " Lookup Fail.")
os.Exit(1)
return nil, errors.New("DNS lookup failed")
}
//var ipv6Flag = false
@@ -125,7 +128,7 @@ func DomainLookUp(host string, ipVersion string, dotServer string, disableOutput
}
if (len(ips) == 1) || (disableOutput) {
return ips[0]
return ips[0], nil
} else {
fmt.Println("Please Choose the IP You Want To TraceRoute")
for i, ip := range ips {
@@ -144,13 +147,17 @@ func DomainLookUp(host string, ipVersion string, dotServer string, disableOutput
fmt.Println("Your Option is invalid")
os.Exit(3)
}
return ips[index]
return ips[index], nil
}
}
func GetenvDefault(key, defVal string) string {
val, ok := os.LookupEnv(key)
if ok {
_, ok := os.LookupEnv("NEXTTRACE_DEBUG")
if ok {
fmt.Println("ENV", key, "detected as", val)
}
return val
}
return defVal
@@ -182,3 +189,38 @@ func GetHostAndPort() (host string, port string) {
}
return
}
func GetProxy() *url.URL {
proxyURLStr := GetenvDefault("NEXTTRACE_PROXY", "")
if proxyURLStr == "" {
return nil
}
proxyURL, err := url.Parse(proxyURLStr)
if err != nil {
log.Println("Failed to parse proxy URL:", err)
return nil
}
return proxyURL
}
func GetPowProvider() string {
var powProvider = ""
if PowProviderParam == "" {
powProvider = GetenvDefault("NEXTTRACE_POWPROVIDER", "api.leo.moe")
} else {
powProvider = PowProviderParam
}
if powProvider == "sakura" {
return "pow.nexttrace.owo.13a.com"
}
return ""
}
func StringInSlice(val string, list []string) bool {
for _, v := range list {
if v == val {
return true
}
}
return false
}

View File

@@ -2,8 +2,8 @@ package wshandle
import (
"crypto/tls"
"github.com/xgadget-lab/nexttrace/pow"
"github.com/xgadget-lab/nexttrace/util"
"github.com/nxtrace/NTrace-core/pow"
"github.com/nxtrace/NTrace-core/util"
"log"
"net"
"net/http"
@@ -127,7 +127,11 @@ func (c *WsConn) recreateWsConn() {
// 无环境变量 token
if cacheToken == "" {
// 无cacheToken, 重新获取 token
jwtToken, err = pow.GetToken(fastIp, host, port)
if util.GetPowProvider() == "" {
jwtToken, err = pow.GetToken(fastIp, host, port)
} else {
jwtToken, err = pow.GetToken(util.GetPowProvider(), util.GetPowProvider(), port)
}
if err != nil {
log.Println(err)
os.Exit(1)
@@ -148,6 +152,10 @@ func (c *WsConn) recreateWsConn() {
dialer.TLSClientConfig = &tls.Config{
ServerName: host,
}
proxyUrl := util.GetProxy()
if proxyUrl != nil {
dialer.Proxy = http.ProxyURL(proxyUrl)
}
ws, _, err := websocket.DefaultDialer.Dial(u.String(), requestHeader)
c.Conn = ws
if err != nil {
@@ -171,6 +179,7 @@ func (c *WsConn) recreateWsConn() {
}
func createWsConn() *WsConn {
proxyUrl := util.GetProxy()
//fmt.Println("正在连接 WS")
// 设置终端中断通道
interrupt := make(chan os.Signal, 1)
@@ -178,6 +187,7 @@ func createWsConn() *WsConn {
host, port = util.GetHostAndPort()
// 如果 host 是一个 IP 使用默认域名
if valid := net.ParseIP(host); valid != nil {
fastIp = host
host = "api.leo.moe"
} else {
// 默认配置完成,开始寻找最优 IP
@@ -186,7 +196,11 @@ func createWsConn() *WsConn {
jwtToken, ua := envToken, []string{"Privileged Client"}
err := error(nil)
if envToken == "" {
jwtToken, err = pow.GetToken(fastIp, host, port)
if util.GetPowProvider() == "" {
jwtToken, err = pow.GetToken(fastIp, host, port)
} else {
jwtToken, err = pow.GetToken(util.GetPowProvider(), util.GetPowProvider(), port)
}
if err != nil {
log.Println(err)
os.Exit(1)
@@ -204,6 +218,9 @@ func createWsConn() *WsConn {
dialer.TLSClientConfig = &tls.Config{
ServerName: host,
}
if proxyUrl != nil {
dialer.Proxy = http.ProxyURL(proxyUrl)
}
u := url.URL{Scheme: "wss", Host: fastIp + ":" + port, Path: "/v3/ipGeoWs"}
// log.Printf("connecting to %s", u.String())