Compare commits

...

116 Commits

Author SHA1 Message Date
tsosunchia
2cb13be378 更新部分依赖
upgraded github.com/pelletier/go-toml/v2 v2.1.1 => v2.2.1
upgraded golang.org/x/exp v0.0.0-20240119083558-1b970713d09a => v0.0.0-20240416160154-fe59bbe5cc7f
2024-04-17 19:38:26 +08:00
tsosunchia
7ae4eb13c9 由于部分网络截断icmp data故ttl改为在seq读取 2024-04-17 19:34:01 +08:00
tsosunchia
d1a72458a6 Merge pull request #48 from nxtrace/dependabot/go_modules/github.com/rodaine/table-1.2.0
chore(deps): bump github.com/rodaine/table from 1.1.1 to 1.2.0
2024-04-11 13:45:33 +08:00
tsosunchia
5e3474d029 Merge pull request #47 from nxtrace/dependabot/go_modules/golang.org/x/net-0.24.0
chore(deps): bump golang.org/x/net from 0.22.0 to 0.24.0
2024-04-11 13:44:48 +08:00
dependabot[bot]
a93b7658b7 chore(deps): bump golang.org/x/net from 0.22.0 to 0.24.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.22.0 to 0.24.0.
- [Commits](https://github.com/golang/net/compare/v0.22.0...v0.24.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>
2024-04-11 05:44:40 +00:00
tsosunchia
bbb905f113 Merge pull request #46 from nxtrace/dependabot/go_modules/golang.org/x/sync-0.7.0
chore(deps): bump golang.org/x/sync from 0.6.0 to 0.7.0
2024-04-11 13:43:56 +08:00
dependabot[bot]
5f44fc704d chore(deps): bump github.com/rodaine/table from 1.1.1 to 1.2.0
Bumps [github.com/rodaine/table](https://github.com/rodaine/table) from 1.1.1 to 1.2.0.
- [Release notes](https://github.com/rodaine/table/releases)
- [Commits](https://github.com/rodaine/table/compare/v1.1.1...v1.2.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-08 14:30:49 +00:00
dependabot[bot]
1257fe87b5 chore(deps): bump golang.org/x/sync from 0.6.0 to 0.7.0
Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.6.0 to 0.7.0.
- [Commits](https://github.com/golang/sync/compare/v0.6.0...v0.7.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-08 14:30:34 +00:00
tsosunchia
ea60a671f2 Merge pull request #235 from nxtrace/main
SYNC
2024-04-06 20:24:01 +08:00
tsosunchia
0d6e894a4b Merge pull request #42 from nxtrace/dependabot/go_modules/github.com/stretchr/testify-1.9.0
chore(deps): bump github.com/stretchr/testify from 1.8.4 to 1.9.0
2024-04-06 20:20:20 +08:00
tsosunchia
20069ab9f3 Merge pull request #43 from nxtrace/dependabot/github_actions/softprops/action-gh-release-2
chore(deps): bump softprops/action-gh-release from 1 to 2
2024-04-06 20:20:11 +08:00
tsosunchia
4f05b57fc2 Merge pull request #44 from nxtrace/dependabot/go_modules/golang.org/x/net-0.22.0
chore(deps): bump golang.org/x/net from 0.21.0 to 0.22.0
2024-04-06 20:19:59 +08:00
tsosunchia
190111f6da 修正在ECMP网络下的表现
之前ECMP网络可能会导致一次trace的结果来自不同flow(按icmp id区分的策略下),目前id不再携带TTL信息,因此一次trace的id将保持一致。
 要提交的变更:
	修改:     trace/icmp_ipv4.go
	修改:     trace/icmp_ipv6.go
2024-04-06 20:07:40 +08:00
tsosunchia
c6eb9bbd2e 修复ft时个别地方未应用色彩参数的问题
交互式变基操作正在进行中;至 cbc511f
 最后完成的命令(1 条命令被执行):
    pick 356e3db 修复ft时个别地方未应用色彩参数的问题
 接下来要执行的命令(剩余 1 条命令):
    pick 9ee7c3f 修正在ECMP网络下的表现 之前ECMP网络可能会导致一次trace的结果来自不同flow(按icmp id区分的策略下),目前id不再携带TTL信息,因此一次trace的id将保持一致。  要提交的变更: 	修改:     trace/icmp_ipv4.go 	修改:     trace/icmp_ipv6.go
 您在执行将分支 'main' 变基到 'cbc511f' 的操作。

 要提交的变更:
	修改:     fast_trace/fast_trace.go
2024-04-06 20:07:17 +08:00
tsosunchia
cbc511f097 修改一些显示问题,对于FASTTRACE/TESTFILE功能应用NO_COLOR属性,对于TESTFILE应用IP隐匿功能。
修改:     fast_trace/fast_trace.go
2024-03-31 12:42:20 +08:00
tsosunchia
66422c4661 Merge pull request #233 from nxtrace/main
update README.md
2024-03-31 00:14:56 +08:00
tsosunchia
b6828b4db1 update README.md 2024-03-31 00:13:32 +08:00
dependabot[bot]
0a750bc6d0 chore(deps): bump golang.org/x/net from 0.21.0 to 0.22.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.21.0 to 0.22.0.
- [Commits](https://github.com/golang/net/compare/v0.21.0...v0.22.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>
2024-03-11 14:49:20 +00:00
dependabot[bot]
47612c022d chore(deps): bump softprops/action-gh-release from 1 to 2
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 1 to 2.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v1...v2)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-11 14:08:40 +00:00
dependabot[bot]
42bf45c2c8 chore(deps): bump github.com/stretchr/testify from 1.8.4 to 1.9.0
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.4 to 1.9.0.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.8.4...v1.9.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-04 14:27:52 +00:00
tsosunchia
8ac1a6bacd Merge pull request #231 from nxtrace/main
SYNC
2024-02-21 09:33:09 +08:00
tsosunchia
f96c3e5139 Merge pull request #41 from nxtrace/dependabot/go_modules/github.com/tidwall/gjson-1.17.1
chore(deps): bump github.com/tidwall/gjson from 1.17.0 to 1.17.1
2024-02-19 23:57:22 +08:00
dependabot[bot]
c46907b881 chore(deps): bump github.com/tidwall/gjson from 1.17.0 to 1.17.1
Bumps [github.com/tidwall/gjson](https://github.com/tidwall/gjson) from 1.17.0 to 1.17.1.
- [Commits](https://github.com/tidwall/gjson/compare/v1.17.0...v1.17.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-19 14:27:38 +00:00
tsosunchia
7afc4c5104 fix issue: https://github.com/nxtrace/NTrace-V1/issues/40
要提交的变更:
	修改:     ipgeo/ip2region.go
2024-02-15 18:00:31 +08:00
tsosunchia
27e560fbde golang 1.22 2024-02-12 22:51:23 +08:00
tsosunchia
1dc18cfff8 Merge pull request #39 from nxtrace/dependabot/go_modules/golang.org/x/net-0.21.0
chore(deps): bump golang.org/x/net from 0.20.0 to 0.21.0
2024-02-12 23:42:25 +09:00
dependabot[bot]
b16dabac7c chore(deps): bump golang.org/x/net from 0.20.0 to 0.21.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.20.0 to 0.21.0.
- [Commits](https://github.com/golang/net/compare/v0.20.0...v0.21.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>
2024-02-12 14:39:04 +00:00
tsosunchia
760e751076 设置latency测试时的fallback 2024-02-05 16:31:07 +08:00
tsosunchia
a82be1b5cf 更新依赖 2024-02-05 16:26:34 +08:00
tsosunchia
4ba76c97fe Merge pull request #38 from nxtrace/dependabot/go_modules/github.com/rodaine/table-1.1.1
chore(deps): bump github.com/rodaine/table from 1.1.0 to 1.1.1
2024-01-22 22:42:34 +08:00
dependabot[bot]
9900bff41a chore(deps): bump github.com/rodaine/table from 1.1.0 to 1.1.1
Bumps [github.com/rodaine/table](https://github.com/rodaine/table) from 1.1.0 to 1.1.1.
- [Release notes](https://github.com/rodaine/table/releases)
- [Commits](https://github.com/rodaine/table/compare/v1.1.0...v1.1.1)

---
updated-dependencies:
- dependency-name: github.com/rodaine/table
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-22 14:29:57 +00:00
tsosunchia
e81a8f9fdc Merge pull request #36 from nxtrace/dependabot/go_modules/golang.org/x/net-0.20.0
chore(deps): bump golang.org/x/net from 0.19.0 to 0.20.0
2024-01-15 22:41:21 +08:00
dependabot[bot]
e3346ff901 chore(deps): bump golang.org/x/net from 0.19.0 to 0.20.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.19.0 to 0.20.0.
- [Commits](https://github.com/golang/net/compare/v0.19.0...v0.20.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>
2024-01-15 14:36:46 +00:00
tsosunchia
70034a81f8 Merge pull request #34 from nxtrace/dependabot/go_modules/golang.org/x/sync-0.6.0 2024-01-09 10:07:05 +08:00
dependabot[bot]
eb0ac2565d chore(deps): bump golang.org/x/sync from 0.5.0 to 0.6.0
Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.5.0 to 0.6.0.
- [Commits](https://github.com/golang/sync/compare/v0.5.0...v0.6.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-08 14:28:20 +00:00
tsosunchia
757ff4232b Merge pull request #223 from nxtrace/main
update readme
2023-12-20 15:38:17 +08:00
tsosunchia
4dda237a57 update readme
更换ip反馈的帖子链接,从issue->discussion
2023-12-20 15:37:03 +08:00
tsosunchia
cfec8df6a4 Merge pull request #221 from nxtrace/main
chore: SYNC
2023-12-20 13:57:38 +08:00
tsosunchia
f76c9401f9 update credit 2023-12-20 13:52:08 +08:00
tsosunchia
9536cf345c 更新依赖
go: upgraded github.com/pelletier/go-toml/v2 v2.1.0 => v2.1.1
go: upgraded github.com/spf13/viper v1.18.1 => v1.18.2
go: upgraded golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb => v0.0.0-20231219180239-dc181d75b848
2023-12-20 13:45:07 +08:00
tsosunchia
f282cf8b8c Merge pull request #33 from nxtrace/dependabot/github_actions/actions/upload-artifact-4
chore(deps): bump actions/upload-artifact from 3 to 4
2023-12-18 22:49:13 +08:00
dependabot[bot]
01fb27b7d7 chore(deps): bump actions/upload-artifact from 3 to 4
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3 to 4.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v3...v4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-18 14:48:33 +00:00
tsosunchia
3133978195 Merge pull request #213 from nxtrace/main
chore: SYNC
2023-12-14 15:16:55 +08:00
tsosunchia
c9dc71cd24 Merge branch 'nxtrace:main' into main 2023-12-14 15:13:43 +08:00
tsosunchia
c67e46bf4f 替换svg 2023-12-14 14:57:45 +08:00
tsosunchia
5d796ce5cd 版本信息输出时应用色彩参数 2023-12-14 14:51:10 +08:00
tsosunchia
96e0558fef Merge pull request #32 from nxtrace/dependabot/go_modules/github.com/spf13/viper-1.18.1
chore(deps): bump github.com/spf13/viper from 1.18.0 to 1.18.1
2023-12-11 23:08:39 +08:00
tsosunchia
662e482593 Merge pull request #31 from nxtrace/dependabot/github_actions/actions/setup-go-5
chore(deps): bump actions/setup-go from 4 to 5
2023-12-11 22:40:36 +08:00
dependabot[bot]
e60a5aedd9 chore(deps): bump github.com/spf13/viper from 1.18.0 to 1.18.1
Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.18.0 to 1.18.1.
- [Release notes](https://github.com/spf13/viper/releases)
- [Commits](https://github.com/spf13/viper/compare/v1.18.0...v1.18.1)

---
updated-dependencies:
- dependency-name: github.com/spf13/viper
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-11 14:38:52 +00:00
dependabot[bot]
559cb478ab chore(deps): bump actions/setup-go from 4 to 5
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 4 to 5.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v4...v5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-11 14:18:40 +00:00
tsosunchia
2598fb4d56 686用一键脚本也指向386 2023-12-08 17:31:43 +08:00
tsosunchia
21a92e1f89 高亮显示扩充 2023-12-08 16:57:01 +08:00
tsosunchia
ef0631fdab fix: 可能发生资源泄漏,在 for 循环中调用 defer 2023-12-08 16:16:38 +08:00
tsosunchia
5c4aa0c2de 更新依赖 2023-12-08 16:11:55 +08:00
tsosunchia
d0c1459752 fmt 2023-12-08 16:06:58 +08:00
tsosunchia
156f8914d8 删除一些没必要的赋值 2023-12-08 16:01:06 +08:00
tsosunchia
de15063be1 Merge pull request #210 from nxtrace/main
homepage部分显示BUG
2023-12-06 16:30:13 +08:00
tsosunchia
af5259e484 homepage部分显示BUG 2023-12-06 16:29:39 +08:00
tsosunchia
5e95aac500 Merge pull request #205 from nxtrace/main
chore: SYNC
2023-12-06 11:53:30 +08:00
tsosunchia
bc267f5b74 update readme 2023-12-06 11:52:05 +08:00
tsosunchia
dede4ed530 主页地址改为超链接形式 2023-12-05 13:49:31 +08:00
tsosunchia
ba2354c429 Merge pull request #204 from nxtrace/main
chore: SYNC
2023-12-05 13:45:08 +08:00
tsosunchia
03394df927 更新主页地址 2023-12-05 13:44:30 +08:00
tsosunchia
1fd3288fb9 Merge pull request #29 from nxtrace/dependabot/go_modules/golang.org/x/net-0.19.0
chore(deps): bump golang.org/x/net from 0.18.0 to 0.19.0
2023-12-05 12:26:09 +08:00
tsosunchia
44eee91c31 替换下载中心至自建 2023-12-05 12:25:28 +08:00
dependabot[bot]
e593ad8fce chore(deps): bump golang.org/x/net from 0.18.0 to 0.19.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.18.0 to 0.19.0.
- [Commits](https://github.com/golang/net/compare/v0.18.0...v0.19.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-12-04 14:58:03 +00:00
tsosunchia
533dacc9ce update credit 2023-12-03 20:31:53 +08:00
tsosunchia
fa30750190 Merge pull request #201 from nxtrace/main
chore: sync
2023-12-02 13:23:47 +08:00
tsosunchia
ffa7bb1d28 update credit 2023-12-01 18:34:42 +08:00
tsosunchia
c0455ca8e7 api变更 2023-12-01 16:32:44 +08:00
tsosunchia
faa3daa0c4 更新一键安装脚本SSL 2023-12-01 11:15:17 +08:00
tsosunchia
fc88c9be5c update readme 2023-11-30 17:14:50 +08:00
tsosunchia
f5d1a606b3 add param: support disable color output 2023-11-30 17:11:14 +08:00
tsosunchia
b32947a824 update credit 2023-11-30 16:12:47 +08:00
tsosunchia
36507ad3b5 reporter.go 未检查造成的越界 2023-11-23 10:23:30 +08:00
tsosunchia
9a3f250b9b Merge pull request #199 from nxtrace/main
update credit
2023-11-21 17:42:18 +08:00
tsosunchia
8adceb8d77 update credit 2023-11-21 17:37:46 +08:00
tsosunchia
7912af8481 Merge pull request #197 from nxtrace/main
fix bug: nil pointer dereference
2023-11-17 19:08:00 +08:00
tsosunchia
4bef8b918a fix bug: nil pointer dereference 2023-11-17 19:00:34 +08:00
tsosunchia
690f7346d0 Merge pull request #195 from nxtrace/main
chore: SYNC
2023-11-17 17:29:46 +08:00
tsosunchia
d82a521954 Update bug_report.md 2023-11-17 17:26:23 +08:00
tsosunchia
0b7d01fb21 移除route参数 2023-11-15 10:19:00 +08:00
tsosunchia
2fed1d152f chore: 更新依赖 2023-11-13 17:19:05 +08:00
tsosunchia
98c0fa38ca 可设置是否隐匿目的IP 2023-11-13 11:23:07 +08:00
tsosunchia
cb63e9b61c Merge pull request #22 from fakeboboliu/main
add source ip support to macOS rootless solution
2023-11-12 00:20:18 +08:00
bobo liu
e4626c4f82 notice silver-bullet of permission issue 2023-11-12 00:11:11 +08:00
bobo liu
47698be2ed add source ip support for macOS rootless solution
do you guys not have macos devices?
2023-11-11 21:38:28 +08:00
tsosunchia
ee0ebb126c Delete CNAME 2023-11-10 09:53:54 +08:00
tsosunchia
1b59210eb1 Merge pull request #191 from nxtrace/main
chore: SYNC
2023-11-09 16:31:25 +08:00
tsosunchia
ed518d175b Merge pull request #21 from huiming23344/main
docs: Clarify the steps in the installation guide
2023-11-09 16:29:07 +08:00
Huiming
9f67ea5e9b docs: Clarify the steps in the installation guide 2023-11-09 15:33:47 +08:00
tsosunchia
d98d2f7ee5 chore(deps): bump golang.org/x/text from 0.13.0 to 0.14.0 2023-11-08 16:17:07 +08:00
tsosunchia
e0b874a687 增加异常处理,在用户输入错误时 2023-11-08 16:13:59 +08:00
tsosunchia
b39657ca5b Merge pull request #20 from nxtrace/dependabot/go_modules/github.com/fatih/color-1.16.0
chore(deps): bump github.com/fatih/color from 1.15.0 to 1.16.0
2023-11-07 08:28:47 +08:00
dependabot[bot]
c79387ff75 chore(deps): bump github.com/fatih/color from 1.15.0 to 1.16.0
Bumps [github.com/fatih/color](https://github.com/fatih/color) from 1.15.0 to 1.16.0.
- [Release notes](https://github.com/fatih/color/releases)
- [Commits](https://github.com/fatih/color/compare/v1.15.0...v1.16.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-07 00:25:23 +00:00
tsosunchia
e6b2d975b4 Merge pull request #19 from nxtrace/dependabot/go_modules/github.com/gorilla/websocket-1.5.1
chore(deps): bump github.com/gorilla/websocket from 1.5.0 to 1.5.1
2023-11-07 08:24:45 +08:00
tsosunchia
33c1af9f50 Merge pull request #18 from nxtrace/dependabot/go_modules/golang.org/x/sync-0.5.0
chore(deps): bump golang.org/x/sync from 0.4.0 to 0.5.0
2023-11-07 08:23:38 +08:00
dependabot[bot]
da825c18cc chore(deps): bump github.com/gorilla/websocket from 1.5.0 to 1.5.1
Bumps [github.com/gorilla/websocket](https://github.com/gorilla/websocket) from 1.5.0 to 1.5.1.
- [Release notes](https://github.com/gorilla/websocket/releases)
- [Commits](https://github.com/gorilla/websocket/compare/v1.5.0...v1.5.1)

---
updated-dependencies:
- dependency-name: github.com/gorilla/websocket
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 14:57:48 +00:00
dependabot[bot]
4adba2b59d chore(deps): bump golang.org/x/sync from 0.4.0 to 0.5.0
Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.4.0 to 0.5.0.
- [Commits](https://github.com/golang/sync/compare/v0.4.0...v0.5.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 14:57:44 +00:00
tsosunchia
65d8ac5c14 修改credit 2023-11-05 16:16:59 +08:00
tsosunchia
7472398c26 Merge pull request #186 from nxtrace/main
chore: 同步
2023-11-05 15:41:12 +08:00
tsosunchia
b2870a823f 修改默认行为,当指定v4/v6时自动选择第一个IP方便脚本使用 2023-11-03 01:21:53 +08:00
tsosunchia
f82af5f9c5 ipv6 trace 正序输出 2023-11-03 00:47:42 +08:00
tsosunchia
9eda2d2a30 chore: 更新依赖 2023-10-31 04:03:50 +08:00
tsosunchia
1a4a15eb74 修复使用NEXTTRACE_HOSTPORT环境变量时不支持IPv6反代地址的问题 2023-10-31 04:03:32 +08:00
tsosunchia
f5556fea5d Merge pull request #184 from nxtrace/main
chore: sync
2023-10-27 21:16:42 +08:00
tsosunchia
d760e75810 fix bug: 当接收到由自身发出的DestinationUnreachable包时视为有效信息,此增强由 @XQZR 提出。 2023-10-20 00:46:58 +08:00
tsosunchia
99409089b2 update credit 2023-10-14 22:32:12 +08:00
tsosunchia
2040497d89 Merge pull request #182 from nxtrace/main
chore: 同步至v1.2.3
2023-10-14 15:18:22 +08:00
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
30 changed files with 872 additions and 813 deletions

View File

@@ -17,6 +17,11 @@ copyright: [v2fly](https://github.com/v2fly)
除非特殊情况,请完整填写所有问题。不按模板发的 issue 将直接被关闭。
如果你遇到的问题不是 nexttrace 的 bug比如你不清楚如何配置请在 https://github.com/nxtrace/NTrace-core/discussions 进行讨论。
-->
## 本项目是基于Linux/macOS的请确认您遇到的问题是否在Linux或macOS上存在。
<!-- 是/否 -->
<!-- 对于只出现在Windows上的问题本项目有时无法解决请知悉 -->
## 你正在使用哪个版本的 nexttrace
@@ -39,6 +44,8 @@ copyright: [v2fly](https://github.com/v2fly)
## 请附上出错时软件输出的错误信息
<!-- 是/否 -->
## 是否查询过本仓库wiki有没有类似错误
<!-- wiki: https://github.com/sjlleo/nexttrace/wiki -->
<!-- wiki: https://github.com/nxtrace/NTrace-core/wiki -->

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,6 +110,7 @@ jobs:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
GOARM: ${{ matrix.goarm }}
GOMIPS: ${{ matrix.gomips }}
CGO_ENABLED: 0
steps:
- name: Checkout codebase
@@ -117,15 +124,18 @@ 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
echo "COMMIT_SHA1=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
- name: Set up Go
uses: actions/setup-go@v4
uses: actions/setup-go@v5
with:
go-version: '1.21'
go-version: '1.22'
- name: Get project dependencies
run: go mod download
- name: Build
@@ -136,14 +146,14 @@ jobs:
-X 'github.com/nxtrace/NTrace-core/config.CommitID=${COMMIT_SHA1}'\
-w -s"
- name: Upload files to Artifacts
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ${{ env.ASSET_NAME }}
path: |
dist/${{ env.ASSET_NAME }}
- name: Release
if: startsWith(github.ref, 'refs/tags/v')
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@v2
with: # 将下述可执行文件 release 上去
draft: true # Release草稿
files: |

View File

@@ -29,9 +29,9 @@ jobs:
os: [windows-latest, ubuntu-latest, macos-latest]
steps:
- name: Set up Go
uses: actions/setup-go@v4
uses: actions/setup-go@v5
with:
go-version: '1.21'
go-version: '1.22'
check-latest: true
- name: Checkout codebase
uses: actions/checkout@v4

1
CNAME
View File

@@ -1 +0,0 @@
mtr.moe

111
README.md
View File

@@ -10,6 +10,10 @@
<h4 align="center">An open source visual routing tool that pursues light weight, developed using Golang.</h4>
---------------------------------------
<h6 align="center">HomePage: www.nxtrace.org</h6>
<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">
@@ -17,36 +21,34 @@
<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">
<a href="https://www.nxtrace.org/downloads">
<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>
## 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">
<img src="https://assets.nxtrace.org/dmit.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">
<img src="https://assets.nxtrace.org/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 href="https://portal.saltyfish.io" >
<img src="https://assets.nxtrace.org/snapstack.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.
We are extremely grateful to [DMIT](https://dmit.io), [Misaka](https://misaka.io) and [SnapStack](https://portal.saltyfish.io) 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.
@@ -57,7 +59,7 @@ Please note, there are exceptions to this synchronization. If a version of NTrac
* One-click installation script
```shell
bash -c "$(curl http://nexttrace-io-leomoe-api-a0.shop/nt_install_v1.sh)"
curl nxtrace.org/nt |bash
```
* Arch Linux AUR installation command
* Directly download bin package (only supports amd64)
@@ -109,7 +111,7 @@ Please note, there are exceptions to this synchronization. If a version of NTrac
### Manual Install
* Download the precompiled 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.
For users not covered by the above methods, please go directly to [Release](https://www.nxtrace.org/downloads) 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.
@@ -119,10 +121,15 @@ Please note, there are exceptions to this synchronization. If a version of NTrac
After installing Go >= 1.20 yourself, you can use the following command to install
```shell
go install github.com/nxtrace/Ntrace-V1@latest
go install github.com/nxtrace/NTrace-core@latest
```
*because of the version constraints conflict, you can not install `NTrace-V1` by this*
After installation, the executable is in the `$GOPATH/bin` directory. If you have not set `GOPATH`, it is in the `$HOME/go/bin` directory.
The binary file name is consistent with the project name. You need to replace the `nexttrace` command below with `NTrace-core`.
If you want to be consistent with the commands below, you can rename the binary after executing the `go install` command
```shell
mv $GOPATH/bin/NTrace-core $GOPATH/bin/nexttrace
```
### Get Started
@@ -141,7 +148,7 @@ nexttrace --table 1.0.0.1
nexttrace --raw 1.0.0.1
nexttrace --json 1.0.0.1
# IPv4/IPv6 Resolve Only
# IPv4/IPv6 Resolve Only, and automatically select the first IP when there are multiple IPs
nexttrace --ipv4 g.co
nexttrace --ipv6 g.co
@@ -150,7 +157,7 @@ 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
# MapTrace URL: https://api.nxtrace.org/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
@@ -171,6 +178,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
@@ -210,6 +228,8 @@ nexttrace --parallel-requests 1 www.hkix.net
# Start Trace with TTL of 5, end at TTL of 10
nexttrace --first 5 --max-hops 10 www.decix.net
# In addition, an ENV is provided to set whether to hide the destination IP
export NEXTTRACE_ENABLEHIDDENDSTIP=1
# Turn off the IP reverse parsing function
nexttrace --no-rdns www.bbix.net
@@ -227,6 +247,11 @@ nexttrace --psize 1024 example.com
# ╭╯
# ╰AS37963 Aliyun「ALIDNS.COM『ALIDNS.COM』」
nexttrace --route-path www.time.com.my
# Disable color output
nexttrace --nocolor 1.1.1.1
# or use ENV
export NO_COLOR=1
```
`NextTrace` supports users to select their own IP API (currently supports: `LeoMoeAPI`, `IP.SB`, `IPInfo`, `IPInsight`, `IPAPI.com`, `Ip2region`, `IPInfoLocal`, `CHUNZHEN`)
@@ -258,8 +283,8 @@ nexttrace --data-provider IPAPI.com --max-hops 20 --tcp --port 443 --queries 5 -
nexttrace -tcp --queries 2 --parallel-requests 1 --table --route-path 2001:4860:4860::8888
Equivalent to:
nexttrace -d IPAPI.com -m 20 -T -p 443 -q 5 -n 1.1.1.1
nexttrace -T -q 2 --parallel-requests 1 -t -R 2001:4860:4860::8888
nexttrace -d ip-api.com -m 20 -T -p 443 -q 5 -n 1.1.1.1
nexttrace -T -q 2 --parallel-requests 1 -t -P 2001:4860:4860::8888
```
### IP Database
@@ -285,15 +310,16 @@ Usage: nexttrace [-h|--help] [-4|--ipv4] [-6|--ipv6] [-T|--tcp] [-U|--udp]
<integer>] [--parallel-requests <integer>] [-m|--max-hops
<integer>] [-d|--data-provider
(Ip2region|ip2region|IP.SB|ip.sb|IPInfo|ipinfo|IPInsight|ipinsight|IPAPI.com|ip-api.com|IPInfoLocal|ipinfolocal|chunzhen|LeoMoeAPI|leomoeapi|disable-geoip)]
[-n|--no-rdns] [-a|--always-rdns] [-P|--route-path]
[-r|--report] [--dn42] [-o|--output] [-t|--table] [--raw]
[-j|--json] [-c|--classic] [-f|--first <integer>] [-M|--map]
[--pow-provider (api.nxtrace.org|sakura)] [-n|--no-rdns]
[-a|--always-rdns] [-P|--route-path] [-r|--report] [--dn42]
[-o|--output] [-t|--table] [--raw] [-j|--json] [-c|--classic]
[-f|--first <integer>] [-M|--map] [-e|--disable-mpls]
[-v|--version] [-s|--source "<value>"] [-D|--dev "<value>"]
[-R|--route] [-z|--send-time <integer>] [-i|--ttl-time
<integer>] [--timeout <integer>] [--psize <integer>]
[_positionalArg_nexttrace_31 "<value>"] [--dot-server
[-z|--send-time <integer>] [-i|--ttl-time <integer>]
[--timeout <integer>] [--psize <integer>]
[_positionalArg_nexttrace_32 "<value>"] [--dot-server
(dnssb|aliyun|dnspod|google|cloudflare)] [-g|--language
(en|cn)]
(en|cn)] [--file "<value>"] [-C|--nocolor]
Arguments:
@@ -324,9 +350,9 @@ Arguments:
IPInfo, IPInsight, IP-API.com, Ip2region,
IPInfoLocal, CHUNZHEN, disable-geoip].
Default: LeoMoeAPI
--pow-provider Choose PoW Provider [api.leo.moe, sakura]
--pow-provider Choose PoW Provider [api.nxtrace.org, sakura]
For China mainland users, please use
sakura. Default: api.leo.moe
sakura. Default: api.nxtrace.org
-n --no-rdns Do not resolve IP addresses to their
domain names
-a --always-rdns Always resolve IP addresses to their
@@ -350,7 +376,6 @@ Arguments:
-s --source Use source src_addr for outgoing packets
-D --dev Use the following Network Devices as the
source address in outgoing packets
-R --route Show Routing Table [Provided By BGP.Tools]
-z --send-time Set how many [milliseconds] between
sending each packet.. Useful when some
routers use rate-limit for ICMP messages.
@@ -364,11 +389,13 @@ Arguments:
connection.. Default: 1000
--psize Set the packet size (payload size).
Default: 52
--_positionalArg_nexttrace_31 IP Address or domain name
--_positionalArg_nexttrace_32 IP Address or domain name
--dot-server Use DoT Server for DNS Parse [dnssb,
aliyun, dnspod, google, cloudflare]
-g --language Choose the language for displaying [en,
cn]. Default: cn
--file Read IP Address or domain name from file
-C --nocolor Disable Colorful Output
```
## Project screenshot
@@ -391,7 +418,7 @@ This software is still in the early stages of development and may have many flaw
[https://github.com/nxtrace/nexttracewebapi](https://github.com/nxtrace/nexttracewebapi)
## LeoMoeAPI Credit
## LeoMoeAPI Credits
NextTrace focuses on Golang Traceroute implementations, and its LeoMoeAPI geolocation information is not supported by raw data, so a commercial version is not possible.
@@ -403,7 +430,7 @@ The LeoMoeAPI data is subject to copyright restrictions from multiple data sourc
3. In terms of development, I would like to credit missuo and zhshch for their help with Go cross-compilation, design concepts and TCP/UDP Traceroute refactoring, and tsosunchia for their support on TraceMap.
4. I would also like to credit FFEE_CO, TheresaQWQ, stydxm and others for their help. leoMoeAPI has received a lot of support since its first release, so I would like to credit them all!
4. I would also like to credit FFEE_CO, TheresaQWQ, stydxm and others for their help. LeoMoeAPI has received a lot of support since its first release, so I would like to credit them all!
We hope you can give us as much feedback as possible on IP geolocation errors (see issue) so that it can be calibrated in the first place and others can benefit from it.
@@ -416,27 +443,37 @@ 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
[IPInfo](https://ipinfo.io) Provided most of the data support for this project free of charge
[BGP.TOOLS](https://bgp.tools) provided some data support for this project. And we would like to express our sincere gratitude.
[BGP.TOOLS](https://bgp.tools) Provided some data support for this project free of charge
[Vincent Young](https://github.com/missuo) (i@yyt.moe)
[PeeringDB](https://www.peeringdb.com) Provided some data support for this project free of charge
[Sam Sam](https://github.com/samleong123) (samsam123@samsam123.name.my)
[sjlleo](https://github.com/sjlleo) The perpetual leader, founder, and core contributors
[tsosunchia](https://github.com/tsosunchia)
[tsosunchia](https://github.com/tsosunchia) The project chair, infra maintainer, and core contributors
[Vincent Young](https://github.com/missuo)
[zhshch2002](https://github.com/zhshch2002)
[Sam Sam](https://github.com/samleong123)
[waiting4new](https://github.com/waiting4new)
[FFEE_CO](https://github.com/fkx4-p)
[bobo liu](https://github.com/fakeboboliu)
[YekongTAT](https://github.com/isyekong)
### Others
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/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)
>- [IP 错误报告汇总帖](https://github.com/orgs/nxtrace/discussions/222) in the GITHUB ISSUES section of this project (Recommended)
>- This project's dedicated correction email: `correction@nxtrace.org` (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/nxtrace/Ntrace-V1/actions/workflows/build.yml) workflow in GitHub Actions.

View File

@@ -11,6 +11,10 @@
<h4 align="center">一款追求轻量化的开源可视化路由跟踪工具。</h4>
---------------------------------------
<h6 align="center">主页www.nxtrace.org</h6>
<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">
@@ -18,38 +22,36 @@
<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">
<a href="https://www.nxtrace.org/downloads">
<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>
## 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">
<img src="https://assets.nxtrace.org/dmit.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">
<img src="https://assets.nxtrace.org/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 href="https://portal.saltyfish.io" >
<img src="https://assets.nxtrace.org/snapstack.svg" width="170.7" height="62.9">
</a>
</div>
我们非常感谢 [DMIT](https://dmit.io) [Misaka](https://misaka.io) 和 [Skywolf](https://skywolf.cloud) 提供了支持本项目所需的网络基础设施。
我们非常感谢 [DMIT](https://dmit.io) [Misaka](https://misaka.io) 和 [SnapStack](https://portal.saltyfish.io) 提供了支持本项目所需的网络基础设施。
## 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会跳过这一有缺陷的版本直接同步到下一个修复了该问题的版本。
@@ -66,7 +68,7 @@ Document Language: [English](README.md) | 简体中文
* 一键安装脚本
```shell
bash -c "$(curl http://nexttrace-io-leomoe-api-a0.shop/nt_install_v1.sh)"
curl nxtrace.org/nt | bash
```
* Arch Linux AUR 安装命令
@@ -120,7 +122,7 @@ Document Language: [English](README.md) | 简体中文
### Manual Install
* 下载预编译的可执行程序
对于以上方法没有涵盖的用户,请直接前往 [Release](https://github.com/nxtrace/Ntrace-V1/releases/latest) 下载编译后的二进制可执行文件。
对于以上方法没有涵盖的用户,请直接前往 [Release](https://www.nxtrace.org/downloads) 下载编译后的二进制可执行文件。
* `Release`里面为很多系统以及不同架构提供了编译好的二进制可执行文件,如果没有可以自行编译。
* 一些本项目的必要依赖在`Windows`上`Golang`底层实现不完全,所以目前`NextTrace`在`Windows`平台出于实验性支持阶段。
@@ -130,9 +132,16 @@ Document Language: [English](README.md) | 简体中文
您可在自行安装Go >= 1.20后,使用以下命令安装
```shell
go install github.com/nxtrace/Ntrace-V1@latest
go install github.com/nxtrace/NTrace-core@latest
```
安装后可执行文件在`$GOPATH/bin`目录下,如果您没有设置`GOPATH`,则在`$HOME/go/bin`目录下。
*由于go.mod文件声明和文件目录冲突的问题你不能用go install命令安装 `NTrace-V1` 版本*
安装后可执行文件在`$GOPATH/bin`目录下,如果您没有设置`GOPATH`,则在`$HOME/go/bin`目录下。
安装后二进制文件名称与项目名称保持一致,你需要将下文中的 `nexttrace` 命令替换为 `NTrace-core` 使用
如果你希望与下文命令保持一致,可以在执行 `go install` 命令后重命名二进制文件
```shell
mv $GOPATH/bin/NTrace-core $GOPATH/bin/nexttrace
```
### Get Started
@@ -152,7 +161,7 @@ nexttrace --table 1.0.0.1
nexttrace --raw 1.0.0.1
nexttrace --json 1.0.0.1
# 只进行IPv4/IPv6解析
# 只进行IPv4/IPv6解析且当多个IP时自动选择第一个IP
nexttrace --ipv4 g.co
nexttrace --ipv6 g.co
@@ -161,7 +170,7 @@ 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
# MapTrace URL: https://api.nxtrace.org/tracemap/html/c14e439e-3250-5310-8965-42a1e3545266.html
# 禁用MPLS显示 使用 --disable-mpls / -e 参数 或 NEXTTRACE_DISABLEMPLS 环境变量
nexttrace --disable-mpls example.com
@@ -182,6 +191,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` 已支持指定网卡进行路由跟踪
@@ -224,6 +244,8 @@ nexttrace --parallel-requests 1 www.hkix.net
# 从TTL为5开始发送探测包直到TTL为10结束
nexttrace --first 5 --max-hops 10 www.decix.net
# 此外还提供了一个ENV可以设置是否隐匿目的IP
export NEXTTRACE_ENABLEHIDDENDSTIP=1
# 关闭IP反向解析功能
nexttrace --no-rdns www.bbix.net
@@ -241,6 +263,10 @@ nexttrace --psize 1024 example.com
# ╭╯
# ╰AS37963 阿里云「ALIDNS.COM『ALIDNS.COM』」
nexttrace --route-path www.time.com.my
# 禁止色彩输出
nexttrace --nocolor 1.1.1.1
# 或者使用环境变量
export NO_COLOR=1
```
`NextTrace`支持用户自主选择 IP 数据库(目前支持:`LeoMoeAPI`, `IP.SB`, `IPInfo`, `IPInsight`, `IPAPI.com`, `Ip2region`, `IPInfoLocal`, `CHUNZHEN`)
@@ -272,7 +298,7 @@ nexttrace -tcp --queries 2 --parallel-requests 1 --table --route-path 2001:4860:
Equivalent to:
nexttrace -d ip-api.com -m 20 -T -p 443 -q 5 -n 1.1.1.1
nexttrace -T -q 2 --parallel-requests 1 -t -R 2001:4860:4860::8888
nexttrace -T -q 2 --parallel-requests 1 -t -P 2001:4860:4860::8888
```
### 全部用法详见 Usage 菜单
@@ -283,15 +309,16 @@ Usage: nexttrace [-h|--help] [-4|--ipv4] [-6|--ipv6] [-T|--tcp] [-U|--udp]
<integer>] [--parallel-requests <integer>] [-m|--max-hops
<integer>] [-d|--data-provider
(Ip2region|ip2region|IP.SB|ip.sb|IPInfo|ipinfo|IPInsight|ipinsight|IPAPI.com|ip-api.com|IPInfoLocal|ipinfolocal|chunzhen|LeoMoeAPI|leomoeapi|disable-geoip)]
[-n|--no-rdns] [-a|--always-rdns] [-P|--route-path]
[-r|--report] [--dn42] [-o|--output] [-t|--table] [--raw]
[-j|--json] [-c|--classic] [-f|--first <integer>] [-M|--map]
[--pow-provider (api.nxtrace.org|sakura)] [-n|--no-rdns]
[-a|--always-rdns] [-P|--route-path] [-r|--report] [--dn42]
[-o|--output] [-t|--table] [--raw] [-j|--json] [-c|--classic]
[-f|--first <integer>] [-M|--map] [-e|--disable-mpls]
[-v|--version] [-s|--source "<value>"] [-D|--dev "<value>"]
[-R|--route] [-z|--send-time <integer>] [-i|--ttl-time
<integer>] [--timeout <integer>] [--psize <integer>]
[_positionalArg_nexttrace_31 "<value>"] [--dot-server
[-z|--send-time <integer>] [-i|--ttl-time <integer>]
[--timeout <integer>] [--psize <integer>]
[_positionalArg_nexttrace_32 "<value>"] [--dot-server
(dnssb|aliyun|dnspod|google|cloudflare)] [-g|--language
(en|cn)]
(en|cn)] [--file "<value>"] [-C|--nocolor]
Arguments:
@@ -322,9 +349,9 @@ Arguments:
IPInfo, IPInsight, IP-API.com, Ip2region,
IPInfoLocal, CHUNZHEN, disable-geoip].
Default: LeoMoeAPI
--pow-provider Choose PoW Provider [api.leo.moe, sakura]
--pow-provider Choose PoW Provider [api.nxtrace.org, sakura]
For China mainland users, please use
sakura. Default: api.leo.moe
sakura. Default: api.nxtrace.org
-n --no-rdns Do not resolve IP addresses to their
domain names
-a --always-rdns Always resolve IP addresses to their
@@ -348,7 +375,6 @@ Arguments:
-s --source Use source src_addr for outgoing packets
-D --dev Use the following Network Devices as the
source address in outgoing packets
-R --route Show Routing Table [Provided By BGP.Tools]
-z --send-time Set how many [milliseconds] between
sending each packet.. Useful when some
routers use rate-limit for ICMP messages.
@@ -362,11 +388,13 @@ Arguments:
connection.. Default: 1000
--psize Set the packet size (payload size).
Default: 52
--_positionalArg_nexttrace_31 IP Address or domain name
--_positionalArg_nexttrace_32 IP Address or domain name
--dot-server Use DoT Server for DNS Parse [dnssb,
aliyun, dnspod, google, cloudflare]
-g --language Choose the language for displaying [en,
cn]. Default: cn
--file Read IP Address or domain name from file
-C --nocolor Disable Colorful Output
```
## 项目截图
@@ -414,20 +442,30 @@ nexttrace --pow-provider sakura
## Credits
[sjlleo](https://github.com/sjlleo) NextTrace 项目永远的领导者、创始人及核心贡献者
[IPInfo](https://ipinfo.io) 无偿提供了本项目大部分数据支持
[BGP.TOOLS](https://bgp.tools) 提供了本项目的一些数据支持,在此表示由衷地感谢。
[BGP.TOOLS](https://bgp.tools) 无偿提供了本项目的一些数据支持
[Vincent Young](https://github.com/missuo) (i@yyt.moe)
[PeeringDB](https://www.peeringdb.com) 无偿提供了本项目的一些数据支持
[Sam Sam](https://github.com/samleong123) (samsam123@samsam123.name.my)
[sjlleo](https://github.com/sjlleo) 项目永远的领导者、创始人及核心贡献者
[tsosunchia](https://github.com/tsosunchia)
[tsosunchia](https://github.com/tsosunchia) 项目现任管理、基础设施运维及核心贡献者
[Vincent Young](https://github.com/missuo)
[zhshch2002](https://github.com/zhshch2002)
[Sam Sam](https://github.com/samleong123)
[waiting4new](https://github.com/waiting4new)
[FFEE_CO](https://github.com/fkx4-p)
[bobo liu](https://github.com/fakeboboliu)
[YekongTAT](https://github.com/isyekong)
## Others
其他第三方 API 尽管集成在本项目内,但是具体的 TOS 以及 AUP请详见第三方 API 官网。如遇到 IP 数据错误,也请直接联系他们纠错。
@@ -438,12 +476,12 @@ nexttrace --pow-provider sakura
## IP 数据以及精准度说明
对于IP相关信息的纠错反馈我们目前开放了两个渠道
>- 本项目的GITHUB ISSUES区中的[IP 错误报告汇总帖](https://github.com/nxtrace/NTrace-core/issues/41)
>- 本项目的纠错专用邮箱: `correction@moeqing.com` 请注意此邮箱仅供IP相关信息纠错专用其他反馈请发送ISSUE
>- 本项目的GITHUB ISSUES区中的[IP 错误报告汇总帖](https://github.com/orgs/nxtrace/discussions/222)
>- 本项目的纠错专用邮箱: `correction@nxtrace.org` 请注意此邮箱仅供IP相关信息纠错专用其他反馈请发送ISSUE
NextTrace 有多个数据源可以选择,目前默认使用的 LeoMoeAPI 为我们项目维护的数据源。
该项目由 OwO Network 的 [Missuo](https://github.com/missuo) && [Leo](https://github.com/sjlleo) 发起,由 [Zhshch](https://github.com/zhshch2002/) 完成最早期架构的编写和指导,后由 Leo 完成了大部分开发工作,现主要交由 [tsosunchia](https://github.com/tsosunchia) 以及 MoeQing Network 完成后续的二开和维护工作。
该项目由 OwO Network 的 [Missuo](https://github.com/missuo) && [Leo](https://github.com/sjlleo) 发起,由 [Zhshch](https://github.com/zhshch2002/) 完成最早期架构的编写和指导,后由 Leo 完成了大部分开发工作,现主要交由 [tsosunchia](https://github.com/tsosunchia) 完成后续的二开和维护工作。
LeoMoeAPI 是 [Leo](https://github.com/sjlleo) 的作品,归属于 Leo Network由 [Leo](https://github.com/sjlleo) 完成整套后端 API 编写,该接口未经允许不可用于任何第三方用途。
@@ -497,8 +535,6 @@ 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

@@ -3,6 +3,7 @@ package cmd
import (
"encoding/json"
"fmt"
"github.com/fatih/color"
"log"
"net"
"os"
@@ -41,8 +42,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"})
powProvider := parser.Selector("", "pow-provider", []string{"api.nxtrace.org", "sakura"}, &argparse.Options{Default: "api.nxtrace.org",
Help: "Choose PoW Provider [api.nxtrace.org, 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"})
@@ -59,7 +60,7 @@ func Excute() {
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"})
router := parser.Flag("R", "route", &argparse.Options{Help: "Show Routing Table [Provided By BGP.Tools]"})
//router := parser.Flag("R", "route", &argparse.Options{Help: "Show Routing Table [Provided By BGP.Tools]"})
packetInterval := parser.Int("z", "send-time", &argparse.Options{Default: 100, Help: "Set how many [milliseconds] between sending each packet.. Useful when some routers use rate-limit for ICMP messages"})
ttlInterval := parser.Int("i", "ttl-time", &argparse.Options{Default: 500, Help: "Set how many [milliseconds] between sending packets groups by TTL. Useful when some routers use rate-limit for ICMP messages"})
timeout := parser.Int("", "timeout", &argparse.Options{Default: 1000, Help: "The number of [milliseconds] to keep probe sockets open before giving up on the connection."})
@@ -69,6 +70,8 @@ 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"})
nocolor := parser.Flag("C", "nocolor", &argparse.Options{Help: "Disable Colorful Output"})
err := parser.Parse(os.Args)
if err != nil {
@@ -77,9 +80,17 @@ func Excute() {
fmt.Print(parser.Usage(err))
return
}
if *nocolor {
color.NoColor = true
} else {
color.NoColor = false
}
if !*jsonPrint {
printer.Version()
}
if *ver {
printer.CopyRight()
os.Exit(0)
@@ -91,7 +102,7 @@ func Excute() {
*port = 80
}
if *fast_trace {
if *fast_trace || *file != "" {
var paramsFastTrace = fastTrace.ParamsFastTrace{
SrcDev: *srcDev,
SrcAddr: *srcAddr,
@@ -102,6 +113,7 @@ func Excute() {
Lang: *lang,
PktSize: *packetSize,
Timeout: time.Duration(*timeout) * time.Millisecond,
File: *file,
}
fastTrace.FastTest(*tcp, *output, paramsFastTrace)
@@ -119,7 +131,12 @@ func Excute() {
}
if strings.Contains(domain, "/") {
domain = strings.Split(domain, "/")[2]
parts := strings.Split(domain, "/")
if len(parts) < 3 {
fmt.Println("Invalid input")
return
}
domain = parts[2]
}
if strings.Contains(domain, "]") {
@@ -158,7 +175,7 @@ func Excute() {
// defer wg.Done()
if strings.ToUpper(*dataOrigin) == "LEOMOEAPI" {
val, ok := os.LookupEnv("NEXTTRACE_DATAPROVIDER")
if strings.ToUpper(*powProvider) != "API.LEO.MOE" {
if strings.ToUpper(*powProvider) != "API.NXTRACE.ORG" {
util.PowProviderParam = *powProvider
}
if ok {
@@ -181,16 +198,20 @@ func Excute() {
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()
@@ -218,7 +239,7 @@ func Excute() {
printer.PrintTraceRouteNav(ip, domain, *dataOrigin, *maxHops, *packetSize)
}
var m trace.Method = ""
var m trace.Method
switch {
case *tcp:
@@ -233,6 +254,7 @@ func Excute() {
*port = 53
}
util.DestIP = ip.String()
var conf = trace.Config{
DN42: *dn42,
SrcAddr: *srcAddr,
@@ -252,6 +274,9 @@ func Excute() {
PktSize: *packetSize,
}
// 暂时弃用
router := new(bool)
*router = false
if !*tablePrint {
if *classicPrint {
conf.RealtimePrinter = printer.ClassicPrinter

View File

@@ -49,36 +49,36 @@ var Beijing = BackBoneCollection{
Location: "北京",
CT163: ISPCollection{
ISPName: CT163,
IP: "ipv4.pek-4134.nexttrace-io-fasttrace-endpoint.win.",
IPv6: "ipv6.pek-4134.nexttrace-io-fasttrace-endpoint.win.",
IP: "ipv4.pek-4134.endpoint.nxtrace.org.",
IPv6: "ipv6.pek-4134.endpoint.nxtrace.org.",
},
CU169: ISPCollection{
ISPName: CU169,
IP: "ipv4.pek-4837.nexttrace-io-fasttrace-endpoint.win.",
IPv6: "ipv6.pek-4837.nexttrace-io-fasttrace-endpoint.win.",
IP: "ipv4.pek-4837.endpoint.nxtrace.org.",
IPv6: "ipv6.pek-4837.endpoint.nxtrace.org.",
},
CU9929: ISPCollection{
ISPName: CU9929,
IP: "ipv4.pek-9929.nexttrace-io-fasttrace-endpoint.win.",
IP: "ipv4.pek-9929.endpoint.nxtrace.org.",
},
CM: ISPCollection{
ISPName: CM,
IP: "ipv4.pek-9808.nexttrace-io-fasttrace-endpoint.win.",
IPv6: "ipv6.pek-9808.nexttrace-io-fasttrace-endpoint.win.",
IP: "ipv4.pek-9808.endpoint.nxtrace.org.",
IPv6: "ipv6.pek-9808.endpoint.nxtrace.org.",
},
CMIN2: ISPCollection{
ISPName: CMIN2,
IP: "ipv4.pek-58807.nexttrace-io-fasttrace-endpoint.win.",
IP: "ipv4.pek-58807.endpoint.nxtrace.org.",
},
EDU: ISPCollection{
ISPName: EDU,
IP: "ipv4.pek-4538.nexttrace-io-fasttrace-endpoint.win.",
IPv6: "ipv6.pek-4538.nexttrace-io-fasttrace-endpoint.win.",
IP: "ipv4.pek-4538.endpoint.nxtrace.org.",
IPv6: "ipv6.pek-4538.endpoint.nxtrace.org.",
},
}
@@ -86,42 +86,42 @@ var Shanghai = BackBoneCollection{
Location: "上海",
CT163: ISPCollection{
ISPName: CT163,
IP: "ipv4.sha-4134.nexttrace-io-fasttrace-endpoint.win.",
IPv6: "ipv6.sha-4134.nexttrace-io-fasttrace-endpoint.win.",
IP: "ipv4.sha-4134.endpoint.nxtrace.org.",
IPv6: "ipv6.sha-4134.endpoint.nxtrace.org.",
},
CTCN2: ISPCollection{
ISPName: CTCN2,
IP: "ipv4.sha-4809.nexttrace-io-fasttrace-endpoint.win.",
IP: "ipv4.sha-4809.endpoint.nxtrace.org.",
},
CU169: ISPCollection{
ISPName: CU169,
IP: "ipv4.sha-4837.nexttrace-io-fasttrace-endpoint.win.",
IPv6: "ipv6.sha-4837.nexttrace-io-fasttrace-endpoint.win.",
IP: "ipv4.sha-4837.endpoint.nxtrace.org.",
IPv6: "ipv6.sha-4837.endpoint.nxtrace.org.",
},
CU9929: ISPCollection{
ISPName: CU9929,
IP: "ipv4.sha-9929.nexttrace-io-fasttrace-endpoint.win.",
IPv6: "ipv6.sha-9929.nexttrace-io-fasttrace-endpoint.win.",
IP: "ipv4.sha-9929.endpoint.nxtrace.org.",
IPv6: "ipv6.sha-9929.endpoint.nxtrace.org.",
},
CM: ISPCollection{
ISPName: CM,
IP: "ipv4.sha-9808.nexttrace-io-fasttrace-endpoint.win.",
IPv6: "ipv6.sha-9808.nexttrace-io-fasttrace-endpoint.win.",
IP: "ipv4.sha-9808.endpoint.nxtrace.org.",
IPv6: "ipv6.sha-9808.endpoint.nxtrace.org.",
},
CMIN2: ISPCollection{
ISPName: CMIN2,
IP: "ipv4.sha-58807.nexttrace-io-fasttrace-endpoint.win.",
IP: "ipv4.sha-58807.endpoint.nxtrace.org.",
},
EDU: ISPCollection{
ISPName: EDU,
IP: "ipv4.sha-4538.nexttrace-io-fasttrace-endpoint.win.",
IPv6: "ipv6.sha-4538.nexttrace-io-fasttrace-endpoint.win.",
IP: "ipv4.sha-4538.endpoint.nxtrace.org.",
IPv6: "ipv6.sha-4538.endpoint.nxtrace.org.",
},
}
@@ -129,20 +129,20 @@ var Guangzhou = BackBoneCollection{
Location: "广州",
CT163: ISPCollection{
ISPName: CT163,
IP: "ipv4.can-4134.nexttrace-io-fasttrace-endpoint.win.",
IPv6: "ipv6.can-4134.nexttrace-io-fasttrace-endpoint.win.",
IP: "ipv4.can-4134.endpoint.nxtrace.org.",
IPv6: "ipv6.can-4134.endpoint.nxtrace.org.",
},
CU169: ISPCollection{
ISPName: CU169,
IP: "ipv4.can-4837.nexttrace-io-fasttrace-endpoint.win.",
IPv6: "ipv6.can-4837.nexttrace-io-fasttrace-endpoint.win.",
IP: "ipv4.can-4837.endpoint.nxtrace.org.",
IPv6: "ipv6.can-4837.endpoint.nxtrace.org.",
},
CM: ISPCollection{
ISPName: CM,
IP: "ipv4.can-9808.nexttrace-io-fasttrace-endpoint.win.",
IPv6: "ipv6.can-9808.nexttrace-io-fasttrace-endpoint.win.",
IP: "ipv4.can-9808.endpoint.nxtrace.org.",
IPv6: "ipv6.can-9808.endpoint.nxtrace.org.",
},
}
@@ -150,23 +150,23 @@ var Hangzhou = BackBoneCollection{
Location: "杭州",
CT163: ISPCollection{
ISPName: CT163,
IP: "ipv4.hgh-4134.nexttrace-io-fasttrace-endpoint.win.",
IPv6: "ipv6.hgh-4134.nexttrace-io-fasttrace-endpoint.win.",
IP: "ipv4.hgh-4134.endpoint.nxtrace.org.",
IPv6: "ipv6.hgh-4134.endpoint.nxtrace.org.",
},
CU169: ISPCollection{
ISPName: CU169,
IP: "ipv4.hgh-4837.nexttrace-io-fasttrace-endpoint.win.",
IP: "ipv4.hgh-4837.endpoint.nxtrace.org.",
},
CM: ISPCollection{
ISPName: CM,
IP: "ipv4.hgh-9808.nexttrace-io-fasttrace-endpoint.win.",
IPv6: "ipv6.hgh-9808.nexttrace-io-fasttrace-endpoint.win.",
IP: "ipv4.hgh-9808.endpoint.nxtrace.org.",
IPv6: "ipv6.hgh-9808.endpoint.nxtrace.org.",
},
// 浙江大学 教育网
EDU: ISPCollection{
ISPName: EDU,
IP: "ipv4.hgh-4538.nexttrace-io-fasttrace-endpoint.win.",
IPv6: "ipv6.hgh-4538.nexttrace-io-fasttrace-endpoint.win.",
IP: "ipv4.hgh-4538.endpoint.nxtrace.org.",
IPv6: "ipv6.hgh-4538.endpoint.nxtrace.org.",
},
}
@@ -175,12 +175,12 @@ var Hefei = BackBoneCollection{
// 中国科学技术大学 教育网
EDU: ISPCollection{
ISPName: EDU,
IP: "ipv4.hfe-4538.nexttrace-io-fasttrace-endpoint.win.",
IPv6: "ipv6.hfe-4538.nexttrace-io-fasttrace-endpoint.win.",
IP: "ipv4.hfe-4538.endpoint.nxtrace.org.",
IPv6: "ipv6.hfe-4538.endpoint.nxtrace.org.",
},
// 中国科学技术大学 科技网
CST: ISPCollection{
ISPName: "中国科学技术大学 科技网 AS7497",
IP: "ipv4.hfe-7497.nexttrace-io-fasttrace-endpoint.win.",
IP: "ipv4.hfe-7497.endpoint.nxtrace.org.",
},
}

View File

@@ -13,45 +13,49 @@ import (
"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() {
@@ -114,7 +118,6 @@ func FastTestv6(tm bool, outEnable bool, paramsFastTrace ParamsFastTrace) {
var c string
oe = outEnable
pFastTracer = paramsFastTrace
fmt.Println("您想测试哪些ISP的路由\n1. 国内四网\n2. 电信\n3. 联通\n4. 移动\n5. 教育网\n6. 全部")
fmt.Print("请选择选项:")
@@ -123,7 +126,9 @@ func FastTestv6(tm bool, outEnable bool, paramsFastTrace ParamsFastTrace) {
c = "1"
}
ft := FastTracer{}
ft := FastTracer{
ParamsFastTrace: paramsFastTrace,
}
// 建立 WebSocket 连接
w := wshandle.New()

View File

@@ -1,7 +1,9 @@
package fastTrace
import (
"bufio"
"fmt"
"github.com/fatih/color"
"github.com/nxtrace/NTrace-core/ipgeo"
"github.com/nxtrace/NTrace-core/printer"
"github.com/nxtrace/NTrace-core/trace"
@@ -12,6 +14,7 @@ import (
"net"
"os"
"os/signal"
"strings"
"time"
)
@@ -30,29 +33,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.Fprintf(color.Output, "%s\n", color.New(color.FgYellow, color.Bold).Sprintf("『%s %s 』", 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 +71,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 +96,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,16 +117,41 @@ 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
}
}
}
}
@@ -120,7 +165,7 @@ func FastTest(tm bool, outEnable bool, paramsFastTrace ParamsFastTrace) {
}
ft := FastTracer{
ParamsFastTrace: pFastTrace,
ParamsFastTrace: paramsFastTrace,
}
// 建立 WebSocket 连接
@@ -156,6 +201,174 @@ func FastTest(tm bool, outEnable bool, paramsFastTrace ParamsFastTrace) {
}
}
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.Fprintf(color.Output, "%s\n",
color.New(color.FgYellow, color.Bold).Sprint("『 "+ip.Desc+"』"),
)
if util.EnableHidDstIP == "" {
fmt.Printf("traceroute to %s, %d hops max, %d bytes packets\n", ip.Ip, paramsFastTrace.MaxHops, paramsFastTrace.PktSize)
} else {
fmt.Printf("traceroute to %s, %d hops max, %d bytes packets\n", util.HideIPPart(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
}
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
err = fp.Close()
if err != nil {
log.Fatal(err)
}
} 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()

36
go.mod
View File

@@ -1,50 +1,50 @@
module github.com/nxtrace/NTrace-core
go 1.21
go 1.22
require (
github.com/akamensky/argparse v1.4.0
github.com/google/gopacket v1.1.19
github.com/oschwald/maxminddb-golang v1.12.0
github.com/spf13/viper v1.17.0
github.com/stretchr/testify v1.8.4
github.com/spf13/viper v1.18.2
github.com/stretchr/testify v1.9.0
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635
github.com/tsosunchia/powclient v0.1.4
golang.org/x/net v0.17.0
golang.org/x/sync v0.4.0
golang.org/x/net v0.24.0
golang.org/x/sync v0.7.0
)
require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/fsnotify/fsnotify v1.7.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/mattn/go-isatty v0.0.20 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/pelletier/go-toml/v2 v2.2.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/sagikazarmark/locafero v0.3.0 // indirect
github.com/sagikazarmark/locafero v0.4.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/afero v1.11.0 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/pflag v1.0.5 // 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
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect
golang.org/x/text v0.14.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/fatih/color v1.16.0
github.com/gorilla/websocket v1.5.1
github.com/lionsoul2014/ip2region v2.11.2+incompatible
github.com/rodaine/table v1.1.0
github.com/tidwall/gjson v1.17.0
github.com/rodaine/table v1.2.0
github.com/tidwall/gjson v1.17.1
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/sys v0.19.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

501
go.sum
View File

@@ -1,147 +1,25 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/akamensky/argparse v1.4.0 h1:YGzvsTqCvbEZhL8zZu2AiA5nq805NZh75JNj4ajn1xc=
github.com/akamensky/argparse v1.4.0/go.mod h1:S5kwC7IuDcEr5VeXtGPRVZ5o/FdhcMlQz4IZQuw64xA=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
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/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=
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
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=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
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/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lionsoul2014/ip2region v2.11.2+incompatible h1:+VRsGcrHz8ewXI/2UzTptJlACsxD/p4xCxuql4u2nKU=
@@ -151,58 +29,54 @@ github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3v
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
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.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/pelletier/go-toml/v2 v2.2.1 h1:9TA9+T8+8CUCO2+WYnDLCgrYi9+omqKXyjDtosvtEhg=
github.com/pelletier/go-toml/v2 v2.2.1/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
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/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rodaine/table v1.2.0 h1:38HEnwK4mKSHQJIkavVj+bst1TEY7j9zhLMWu4QJrMA=
github.com/rodaine/table v1.2.0/go.mod h1:wejb/q/Yd4T/SVmBSRMr7GCq3KlcZp3gyNYdLSBhkaE=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
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/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
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/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
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.17.0 h1:I5txKw7MJasPL/BrfkbA0Jyo/oELqVmux4pR/UxOMfI=
github.com/spf13/viper v1.17.0/go.mod h1:BmMMMLQXSbcHK6KAOiFLz0l5JHrU89OdIRHvsk0+yVI=
github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ=
github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk=
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.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/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
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.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
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.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM=
github.com/tidwall/gjson v1.17.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U=
github.com/tidwall/gjson v1.17.1/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=
@@ -210,326 +84,37 @@ 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.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=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
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=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
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=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY=
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
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.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=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
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.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/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
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=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
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.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/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
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.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=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
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/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=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

View File

@@ -14,7 +14,7 @@ import (
const (
ipDataBasePath = "./ip2region.db"
defaultDownURL = "1"
originURL = "https://ghproxy.com/?q=https://github.com/bqf9979/ip2region/blob/master/data/ip2region.db?raw=true"
originURL = "https://mirror.ghproxy.com/?q=https://github.com/bqf9979/ip2region/blob/master/data/ip2region.db?raw=true"
)
func downloadDataBase() error {

View File

@@ -1,5 +1,12 @@
#!/bin/bash
if [ "$1" = "http" ]; then
protocol="http"
else
protocol="https"
fi
Green_font="\033[32m"
Yellow_font="\033[33m"
Red_font="\033[31m"
@@ -19,6 +26,8 @@ checkSystemArch() {
archParam="amd64"
elif [[ $arch == "i386" ]]; then
archParam="386"
elif [[ $arch == "i686" ]]; then
archParam="386"
elif [[ $arch == "aarch64" ]]; then
archParam="arm64"
elif [[ $arch == "armv7l" ]] || [[ $arch == "armv7ml" ]]; then
@@ -30,13 +39,13 @@ checkSystemArch() {
checkSystemDistribution() {
case "$OSTYPE" in
linux*)
linux*)
osDistribution="linux"
if [ ! -d "/usr/local" ];
then
if [ ! -d "/usr/local" ];
then
downPath="/usr/bin/nexttrace"
else
else
downPath="/usr/local/bin/nexttrace"
fi
@@ -48,63 +57,46 @@ checkSystemDistribution() {
esac
}
getLocation() {
countryCode=$(curl -s "http://ip-api.com/line/?fields=countryCode")
}
installWgetPackage() {
echo -e "${Info} wget 正在安装中..."
# try apt
apt -h &> /dev/null
if [ $? -eq 0 ]; then
# 先更新一下数据源有些机器数据源比较老可能会404
apt update -y &> /dev/null
apt install wget -y &> /dev/null
fi
# try yum
yum -h &> /dev/null
if [ $? -eq 0 ]; then
yum install wget -y &> /dev/null
fi
# try dnf
dnf -h &> /dev/null
if [ $? -eq 0 ]; then
dnf install wget -y &> /dev/null
fi
# try pacman
pacman -h &> /dev/null
if [ $? -eq 0 ]; then
pacman -Sy
pacman -S wget
fi
}
checkWgetPackage() {
wget -h &> /dev/null
if [ $? -ne 0 ]; then
installWgetPackage
fi
}
downloadBinrayFile() {
echo -e "${Info} 获取最新版的 NextTrace 发行版文件信息"
# 简单说明一下Github提供了一个API可以获取最新发行版本的二进制文件下载地址对应的是browser_download_url根据刚刚测得的osDistribution、archParam获取对应的下载地址
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
if [ $? -eq 0 ];
then
changeMode
mv ${Temp_path} ${downPath}
echo -e "${Info} NextTrace 现在已经在您的系统中可用"
for i in {1..3}; do
downloadUrls=$(curl -sL ${protocol}://www.nxtrace.org/api/dist/core/nexttrace_${osDistribution}_${archParam} --connect-timeout 1.5)
if [ $? -eq 0 ]; then
break
fi
done
if [ $? -eq 0 ]; then
primaryUrl=$(echo ${downloadUrls} | awk -F '|' '{print $1}')
backupUrl=$(echo ${downloadUrls} | awk -F '|' '{print $2}')
echo -e "${Info} 正在尝试从 Primary 节点下载 NextTrace"
for i in {1..3}; do
curl -sL ${primaryUrl} -o ${Temp_path} --connect-timeout 1.5
if [ $? -eq 0 ]; then
changeMode
mv ${Temp_path} ${downPath}
echo -e "${Info} NextTrace 现在已经在您的系统中可用"
return
fi
done
if [ -z ${backupUrl} ]; then
echo -e "${Error} 从 Primary 节点下载失败,且 Backup 节点为空,无法下载 NextTrace"
exit 1
fi
echo -e "${Error} 从 Primary 节点下载失败,正在尝试从 Backup 节点下载 NextTrace"
for i in {1..3}; do
curl -sL ${backupUrl} -o ${Temp_path} --connect-timeout 1.5
if [ $? -eq 0 ]; then
changeMode
mv ${Temp_path} ${downPath}
echo -e "${Info} NextTrace 现在已经在您的系统中可用"
return
fi
done
echo -e "${Error} NextTrace 下载失败,请检查您的网络是否正常"
exit 1
else
echo -e "${Error} NextTrace 下载失败,请检查您的网络是否正常"
exit 1
echo -e "${Error} 获取下载地址失败,请检查您的网络是否正常"
exit 1
fi
}
@@ -123,9 +115,10 @@ runBinrayFileHelp() {
checkRootPermit
checkSystemDistribution
checkSystemArch
checkWgetPackage
# Download Procedure
downloadBinrayFile
# Run Procedure
runBinrayFileHelp

View File

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

View File

@@ -4,6 +4,7 @@ import (
"fmt"
"github.com/nxtrace/NTrace-core/config"
"github.com/nxtrace/NTrace-core/trace"
"github.com/nxtrace/NTrace-core/util"
"net"
"github.com/fatih/color"
@@ -23,45 +24,47 @@ func Version() {
}
func CopyRight() {
fmt.Fprintf(color.Output, "\n%s\n%s\n%s %s\n\n%s\n%s %s\n%s %s\n%s %s\n\n%s\n%s\n%s %s\n\n",
color.New(color.FgCyan, color.Bold).Sprintf("%s", "NextTrace CopyRight"),
color.New(color.FgGreen, color.Bold).Sprintf("%s", "NextTrace Project Creator"),
color.New(color.FgWhite, color.Bold).Sprintf("%s", "Leo"),
color.New(color.FgHiBlack, color.Bold).Sprintf("%s", "i@leo.moe"),
color.New(color.FgGreen, color.Bold).Sprintf("%s", "NextTrace Project Maintainer"),
color.New(color.FgWhite, color.Bold).Sprintf("%s", "Tso"),
color.New(color.FgHiBlack, color.Bold).Sprintf("%s", "tsosunchia@gmail.com"),
color.New(color.FgWhite, color.Bold).Sprintf("%s", "Vincent"),
color.New(color.FgHiBlack, color.Bold).Sprintf("%s", "i@vincent.moe"),
color.New(color.FgWhite, color.Bold).Sprintf("%s", "Leo"),
color.New(color.FgHiBlack, color.Bold).Sprintf("%s", "i@leo.moe"),
color.New(color.FgCyan, color.Bold).Sprintf("%s", "Special Acknowledgement List"),
color.New(color.FgGreen, color.Bold).Sprintf("%s", "NextTrace Major Contributor"),
color.New(color.FgWhite, color.Bold).Sprintf("%s", "zhshch"),
color.New(color.FgHiBlack, color.Bold).Sprintf("%s", "zhshch@athorx.com"),
)
moeQingOrgCopyRight()
sponsor()
fmt.Fprintf(color.Output, "\n%s\n%s %s\n%s %s\n%s %s, %s, %s, %s\n%s %s\n",
color.New(color.FgCyan, color.Bold).Sprintf("%s", "NextTrace CopyRight"),
//color.New(color.FgGreen, color.Bold).Sprintf("%s", "Contact Us"),
//color.New(color.FgWhite, color.Bold).Sprintf("%s", "Feedback Email:"),
//color.New(color.FgHiBlack, color.Bold).Sprintf("%s", "nt@moeqing.com"),
//color.New(color.FgWhite, color.Bold).Sprintf("%s", "HomePage:"),
//color.New(color.FgHiBlack, color.Bold).Sprintf("%s", "github.com/nxtrace"),
color.New(color.FgWhite, color.Bold).Sprintf("%s", "Honorary Founder:"),
color.New(color.FgHiBlue, color.Bold).Sprintf("%s", "Leo"),
//color.New(color.FgHiBlack, color.Bold).Sprintf("%s", "i@leo.moe"),
color.New(color.FgWhite, color.Bold).Sprintf("%s", "Project Chair:"),
color.New(color.FgHiBlue, color.Bold).Sprintf("%s", "Tso"),
color.New(color.FgWhite, color.Bold).Sprintf("%s", "Core-Developer:"),
color.New(color.FgHiBlue, color.Bold).Sprintf("%s", "Leo"),
//color.New(color.FgHiBlack, color.Bold).Sprintf("%s", "i@leo.moe"),
color.New(color.FgHiBlue, color.Bold).Sprintf("%s", "Vincent"),
//color.New(color.FgHiBlack, color.Bold).Sprintf("%s", "i@vincent.moe"),
color.New(color.FgHiBlue, color.Bold).Sprintf("%s", "zhshch"),
//color.New(color.FgHiBlack, color.Bold).Sprintf("%s", "zhshch@athorx.com"),
color.New(color.FgHiBlue, color.Bold).Sprintf("%s", "Tso"),
//color.New(color.FgHiBlack, color.Bold).Sprintf("%s", "tsosunchia@gmail.com"),
color.New(color.FgWhite, color.Bold).Sprintf("%s", "Infra Maintainer:"),
color.New(color.FgHiBlue, color.Bold).Sprintf("%s", "Tso"),
//color.New(color.FgWhite, color.Bold).Sprintf("%s", "NOC Manager:"),
//color.New(color.FgHiBlue, color.Bold).Sprintf("%s", "YekongTAT"),
//color.New(color.FgHiBlack, color.Bold).Sprintf("%s", "tsosunchia@gmail.com"),
)
//PluginCopyRight()
}
func moeQingOrgCopyRight() {
fmt.Fprintf(color.Output, "%s\n%s %s\n%s %s\n\n",
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"),
color.New(color.FgHiBlack, color.Bold).Sprintf("%s", "haima@peers.cloud"),
)
}
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"),
italic := "\x1b[3m%s\x1b[0m"
formatted := fmt.Sprintf(italic, "(Listed in no particular order)")
fmt.Fprintf(color.Output, "%s\n%s\n%s\n%s\n%s\n",
color.New(color.FgCyan, color.Bold).Sprintf("%s", "NextTrace Sponsored by"),
color.New(color.FgHiYellow, color.Bold).Sprintf("%s", "· DMIT.io"),
color.New(color.FgHiYellow, color.Bold).Sprintf("%s", "· Misaka.io"),
color.New(color.FgHiYellow, color.Bold).Sprintf("%s", "· Saltyfish.io"),
color.New(color.FgHiBlack, color.Bold).Sprintf("%s", formatted),
)
}
@@ -75,11 +78,14 @@ func sponsor() {
func PrintTraceRouteNav(ip net.IP, domain string, dataOrigin string, maxHops int, packetSize int) {
fmt.Println("IP Geo Data Provider: " + dataOrigin)
if ip.String() == domain {
fmt.Printf("traceroute to %s, %d hops max, %d bytes packets\n", ip.String(), maxHops, packetSize)
if util.EnableHidDstIP == "" {
if ip.String() == domain {
fmt.Printf("traceroute to %s, %d hops max, %d bytes packets\n", ip.String(), maxHops, packetSize)
} else {
fmt.Printf("traceroute to %s (%s), %d hops max, %d bytes packets\n", ip.String(), domain, maxHops, packetSize)
}
} else {
fmt.Printf("traceroute to %s (%s), %d hops max, %d bytes packets\n", ip.String(), domain, maxHops, packetSize)
fmt.Printf("traceroute to %s, %d hops max, %d bytes packets\n", util.HideIPPart(ip.String()), maxHops, packetSize)
}
}

View File

@@ -2,6 +2,7 @@ package printer
import (
"fmt"
"github.com/nxtrace/NTrace-core/util"
"net"
"strconv"
"strings"
@@ -12,7 +13,6 @@ import (
func RealtimePrinter(res *trace.Result, ttl int) {
fmt.Printf("%s ", color.New(color.FgHiYellow, color.Bold).Sprintf("%-2d", ttl+1))
// 去重
var latestIP string
tmpMap := make(map[string][]string)
@@ -51,13 +51,25 @@ func RealtimePrinter(res *trace.Result, ttl int) {
fmt.Printf("%4s", "")
}
if net.ParseIP(ip).To4() == nil {
fmt.Fprintf(color.Output, "%s",
color.New(color.FgWhite, color.Bold).Sprintf("%-25s", ip),
)
if util.EnableHidDstIP == "" || ip != util.DestIP {
fmt.Fprintf(color.Output, "%s",
color.New(color.FgWhite, color.Bold).Sprintf("%-25s", ip),
)
} else {
fmt.Fprintf(color.Output, "%s",
color.New(color.FgWhite, color.Bold).Sprintf("%-25s", util.HideIPPart(ip)),
)
}
} else {
fmt.Fprintf(color.Output, "%s",
color.New(color.FgWhite, color.Bold).Sprintf("%-15s", ip),
)
if util.EnableHidDstIP == "" || ip != util.DestIP {
fmt.Fprintf(color.Output, "%s",
color.New(color.FgWhite, color.Bold).Sprintf("%-15s", ip),
)
} else {
fmt.Fprintf(color.Output, "%s",
color.New(color.FgWhite, color.Bold).Sprintf("%-15s", util.HideIPPart(ip)),
)
}
}
i, _ := strconv.Atoi(v[0])
@@ -79,6 +91,12 @@ func RealtimePrinter(res *trace.Result, ttl int) {
fallthrough
case res.Hops[ttl][i].Geo.Asnumber == "23764":
fallthrough
case res.Hops[ttl][i].Geo.Whois == "CTG-CN":
fallthrough
case res.Hops[ttl][i].Geo.Whois == "[CNC-BACKBONE]":
fallthrough
case res.Hops[ttl][i].Geo.Whois == "[CUG-BACKBONE]":
fallthrough
case res.Hops[ttl][i].Geo.Whois == "CMIN2-NET":
fallthrough
case strings.HasPrefix(res.Hops[ttl][i].Address.String(), "59.43."):
@@ -119,6 +137,8 @@ func RealtimePrinter(res *trace.Result, ttl int) {
fallthrough
case res.Hops[ttl][i].Geo.Asnumber == "23764":
fallthrough
case whoisFormat[0] == "[CTG-CN]":
fallthrough
case whoisFormat[0] == "[CNC-BACKBONE]":
fallthrough
case whoisFormat[0] == "[CUG-BACKBONE]":

View File

@@ -114,11 +114,13 @@ func (r *reporter) InitialBaseData() Reporter {
r.targetTTL = uint16(len(r.routeResult.Hops))
for i := uint16(0); i < r.targetTTL; i++ {
traceHop := r.routeResult.Hops[i][0]
if traceHop.Success {
currentIP := traceHop.Address.String()
r.wg.Add(1)
go r.generateRouteReportNode(currentIP, *traceHop.Geo, i)
if i < uint16(len(r.routeResult.Hops)) && len(r.routeResult.Hops[i]) > 0 {
traceHop := r.routeResult.Hops[i][0]
if traceHop.Success {
currentIP := traceHop.Address.String()
r.wg.Add(1)
go r.generateRouteReportNode(currentIP, *traceHop.Geo, i)
}
}
}

View File

@@ -15,6 +15,8 @@ import (
"golang.org/x/net/context"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv4"
"github.com/nxtrace/NTrace-core/trace/internal"
)
type ICMPTracer struct {
@@ -39,6 +41,7 @@ func (t *ICMPTracer) PrintFunc() {
if t.AsyncPrinter != nil {
t.AsyncPrinter(&t.res)
}
// 接收的时候检查一下是不是 3 跳都齐了
if len(t.res.Hops)-1 > ttl {
if len(t.res.Hops[ttl]) == t.NumMeasurements {
if t.RealtimePrinter != nil {
@@ -66,7 +69,7 @@ func (t *ICMPTracer) Execute() (*Result, error) {
var err error
t.icmpListen, err = net.ListenPacket("ip4:1", t.SrcAddr)
t.icmpListen, err = internal.ListenICMP("ip4:1", t.SrcAddr)
if err != nil {
return &t.res, err
}
@@ -147,8 +150,9 @@ func (t *ICMPTracer) listenICMP() {
}
continue
}
ttl := int64(binary.BigEndian.Uint16(msg.Msg[34:36]))
packet_id := strconv.FormatInt(int64(binary.BigEndian.Uint16(msg.Msg[32:34])), 2)
if process_id, ttl, err := reverseID(packet_id); err == nil {
if process_id, _, err := reverseID(packet_id); err == nil {
if process_id == int64(os.Getpid()&0x7f) {
dstip := net.IP(msg.Msg[24:28])
if dstip.Equal(t.DestIP) || dstip.Equal(net.IPv4zero) {
@@ -164,6 +168,9 @@ func (t *ICMPTracer) listenICMP() {
t.handleICMPMessage(msg, 0, rm.Body.(*icmp.TimeExceeded).Data, int(ttl))
case ipv4.ICMPTypeEchoReply:
t.handleICMPMessage(msg, 1, rm.Body.(*icmp.Echo).Data, int(ttl))
//unreachable
case ipv4.ICMPTypeDestinationUnreachable:
t.handleICMPMessage(msg, 2, rm.Body.(*icmp.DstUnreach).Data, int(ttl))
default:
// log.Println("received icmp message of unknown type", rm.Type)
}
@@ -176,6 +183,12 @@ func (t *ICMPTracer) listenICMP() {
}
func (t *ICMPTracer) handleICMPMessage(msg ReceivedMessage, icmpType int8, data []byte, ttl int) {
if icmpType == 2 {
if t.DestIP.String() != msg.Peer.String() {
return
}
}
t.inflightRequestRWLock.RLock()
defer t.inflightRequestRWLock.RUnlock()
@@ -254,15 +267,21 @@ func (t *ICMPTracer) send(ttl int) error {
return nil
}
id := gernerateID(ttl)
//id := gernerateID(ttl)
id := gernerateID(0)
// log.Println("发送的", id)
//data := []byte{byte(ttl)}
data := []byte{byte(0)}
data = append(data, bytes.Repeat([]byte{1}, t.Config.PktSize-5)...)
data = append(data, 0x00, 0x00, 0x4f, 0xff)
icmpHeader := icmp.Message{
Type: ipv4.ICMPTypeEcho, Code: 0,
Body: &icmp.Echo{
ID: id,
//Data: []byte("HELLO-R-U-THERE"),
Data: append(bytes.Repeat([]byte{1}, t.Config.PktSize-4), 0x00, 0x00, 0x4f, 0xff),
Data: data,
Seq: ttl,
},
}

View File

@@ -13,6 +13,8 @@ import (
"golang.org/x/net/context"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv6"
"github.com/nxtrace/NTrace-core/trace/internal"
)
type ICMPTracerv6 struct {
@@ -30,7 +32,7 @@ type ICMPTracerv6 struct {
}
func (t *ICMPTracerv6) PrintFunc() {
// defer t.wg.Done()
defer t.wg.Done()
var ttl = t.Config.BeginHop - 1
for {
if t.AsyncPrinter != nil {
@@ -44,12 +46,12 @@ func (t *ICMPTracerv6) PrintFunc() {
t.RealtimePrinter(&t.res, ttl)
}
ttl++
if ttl == t.final {
if ttl == t.final-1 || ttl >= t.MaxHops-1 {
return
}
}
}
<-time.After(200 * time.Millisecond)
}
}
@@ -65,7 +67,7 @@ func (t *ICMPTracerv6) Execute() (*Result, error) {
var err error
t.icmpListen, err = net.ListenPacket("ip6:58", t.SrcAddr)
t.icmpListen, err = internal.ListenICMP("ip6:58", t.SrcAddr)
if err != nil {
return &t.res, err
}
@@ -78,6 +80,7 @@ func (t *ICMPTracerv6) Execute() (*Result, error) {
t.final = -1
go t.listenICMP()
t.wg.Add(1)
go t.PrintFunc()
for ttl := t.BeginHop; ttl <= t.MaxHops; ttl++ {
t.inflightRequestRWLock.Lock()
@@ -168,8 +171,9 @@ func (t *ICMPTracerv6) listenICMP() {
}
}
ttl := int64(binary.BigEndian.Uint16(msg.Msg[54:56]))
packet_id := strconv.FormatInt(int64(binary.BigEndian.Uint16(msg.Msg[52:54])), 2)
if process_id, ttl, err := reverseID(packet_id); err == nil {
if process_id, _, err := reverseID(packet_id); err == nil {
if process_id == int64(os.Getpid()&0x7f) {
dstip := net.IP(msg.Msg[32:48])
// 无效包本地环回包
@@ -189,6 +193,8 @@ func (t *ICMPTracerv6) listenICMP() {
t.handleICMPMessage(msg, 0, rm.Body.(*icmp.TimeExceeded).Data, int(ttl))
case ipv6.ICMPTypeEchoReply:
t.handleICMPMessage(msg, 1, rm.Body.(*icmp.Echo).Data, int(ttl))
case ipv6.ICMPTypeDestinationUnreachable:
t.handleICMPMessage(msg, 2, rm.Body.(*icmp.DstUnreach).Data, int(ttl))
default:
// log.Println("received icmp message of unknown type", rm.Type)
}
@@ -232,6 +238,11 @@ func (t *ICMPTracerv6) listenICMP() {
}
func (t *ICMPTracerv6) handleICMPMessage(msg ReceivedMessage, icmpType int8, data []byte, ttl int) {
if icmpType == 2 {
if t.DestIP.String() != msg.Peer.String() {
return
}
}
t.inflightRequestRWLock.RLock()
defer t.inflightRequestRWLock.RUnlock()
@@ -250,14 +261,20 @@ func (t *ICMPTracerv6) send(ttl int) error {
if t.final != -1 && ttl > t.final {
return nil
}
id := gernerateID(ttl)
//id := gernerateID(ttl)
id := gernerateID(0)
//data := []byte{byte(ttl)}
data := []byte{byte(0)}
data = append(data, bytes.Repeat([]byte{1}, t.Config.PktSize-5)...)
data = append(data, 0x00, 0x00, 0x4f, 0xff)
icmpHeader := icmp.Message{
Type: ipv6.ICMPTypeEchoRequest, Code: 0,
Body: &icmp.Echo{
ID: id,
//Data: []byte("HELLO-R-U-THERE"),
Data: append(bytes.Repeat([]byte{1}, t.Config.PktSize-4), 0x00, 0x00, 0x4f, 0xff),
Data: data,
Seq: ttl,
},
}

View File

@@ -12,13 +12,14 @@ import (
)
//go:linkname internetSocket net.internetSocket
func internetSocket(ctx context.Context, net string, laddr, raddr interface{}, sotype, proto int, mode string, ctrlCtxFn func(context.Context, string, string, syscall.RawConn) error) (fd unsafe.Pointer, err error)
func internetSocket(ctx context.Context, net string, laddr, raddr any, sotype, proto int, mode string, ctrlCtxFn func(context.Context, string, string, syscall.RawConn) error) (fd unsafe.Pointer, err error)
//go:linkname newIPConn net.newIPConn
func newIPConn(fd unsafe.Pointer) *net.IPConn
var (
errUnknownNetwork = errors.New("unknown network type")
errUnknownIface = errors.New("unknown network interface")
networkMap = map[string]string{
"ip4:icmp": "udp4",
@@ -28,7 +29,6 @@ var (
}
)
// ListenICMP 会造成指定出口IP功能不可使用
func ListenICMP(network string, laddr string) (net.PacketConn, error) {
if os.Getuid() == 0 { // root
return net.ListenPacket(network, laddr)
@@ -38,7 +38,48 @@ func ListenICMP(network string, laddr string) (net.PacketConn, error) {
if nw == "udp6" {
proto = syscall.IPPROTO_ICMPV6
}
isock, err := internetSocket(context.Background(), nw, nil, nil, syscall.SOCK_DGRAM, proto, "listen", nil)
var ifIndex int = -1
if laddr != "" {
la := net.ParseIP(laddr)
if ifaces, err := net.Interfaces(); err == nil {
for _, iface := range ifaces {
addrs, err := iface.Addrs()
if err != nil {
continue
}
for _, addr := range addrs {
if ipnet, ok := addr.(*net.IPNet); ok {
if ipnet.IP.Equal(la) {
ifIndex = iface.Index
break
}
}
}
}
if ifIndex == -1 {
return nil, errUnknownIface
}
} else {
return nil, err
}
}
isock, err := internetSocket(context.Background(), nw, nil, nil, syscall.SOCK_DGRAM, proto, "listen",
func(ctx context.Context, network, address string, c syscall.RawConn) error {
if ifIndex != -1 {
if proto == syscall.IPPROTO_ICMP {
return c.Control(func(fd uintptr) {
syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_BOUND_IF, ifIndex)
})
} else {
return c.Control(func(fd uintptr) {
syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IPV6, syscall.IPV6_BOUND_IF, ifIndex)
})
}
}
return nil
})
if err != nil {
panic(err)
}

File diff suppressed because one or more lines are too long

View File

@@ -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

@@ -7,6 +7,7 @@ import (
"strconv"
"strings"
"sync"
"syscall"
"time"
"github.com/nxtrace/NTrace-core/ipgeo"
@@ -92,7 +93,11 @@ func Traceroute(method Method, config Config) (*Result, error) {
default:
return &Result{}, ErrInvalidMethod
}
return tracer.Execute()
result, err := tracer.Execute()
if err != nil && errors.Is(err, syscall.EPERM) {
err = fmt.Errorf("%w, please run as root", err)
}
return result, err
}
type Result struct {
@@ -141,7 +146,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
}
@@ -200,7 +205,7 @@ func (h *Hop) fetchIPData(c Config) (err error) {
if !c.AlwaysWaitRDNS {
select {
case <-fetchDoneChan:
// When fetch done signal recieved, stop waiting PTR record
// When fetch done signal received, stop waiting PTR record
case ptr := <-rDNSChan:
// process result
if err == nil && len(ptr) > 0 {
@@ -221,9 +226,9 @@ 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
}

View File

@@ -16,10 +16,14 @@ import (
func GetMapUrl(r string) (string, error) {
host, port := util.GetHostAndPort()
fastIp := "api.leo.moe"
var fastIp string
// 如果 host 是一个 IP 使用默认域名
if valid := net.ParseIP(host); valid != nil {
host = "api.leo.moe"
fastIp = host
if len(strings.Split(fastIp, ":")) > 1 {
fastIp = "[" + fastIp + "]"
}
host = "origin-fallback.nxtrace.org"
} else {
// 默认配置完成,开始寻找最优 IP
fastIp = util.GetFastIP(host, port, false)

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.endpoint.nxtrace.org.", "all", "", false)
fmt.Println(ips)
ips = DomainLookUp("pek-4134.nexttrace-io-fasttrace-endpoint.win.", "4", "", false)
ips, _ = DomainLookUp("pek-4134.endpoint.nxtrace.org.", "4", "", false)
fmt.Println(ips)
}

View File

@@ -28,13 +28,20 @@ var FastIpCache = ""
func GetFastIP(domain string, port string, enableOutput bool) string {
proxyUrl := GetProxy()
if proxyUrl != nil {
return "api.leo.moe"
return "origin-fallback.nxtrace.org"
}
if FastIpCache != "" {
return FastIpCache
}
ips, err := net.LookupIP(domain)
var ips []net.IP
var err error
if domain == "origin-fallback.nxtrace.org" {
ips, err = net.LookupIP("api.nxtrace.org")
} else {
ips, err = net.LookupIP(domain)
}
if err != nil {
log.Fatal("DNS resolution failed, please check your system DNS Settings")
}
@@ -60,7 +67,7 @@ func GetFastIP(domain string, port string, enableOutput bool) string {
//if len(ips) > 0 {
if enableOutput {
_, _ = fmt.Fprintf(color.Output, "%s prefered API IP - %s - %s - %s",
_, _ = 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),
@@ -68,6 +75,12 @@ func GetFastIP(domain string, port string, enableOutput bool) string {
)
}
//}
//有些时候真的啥都不通,还是挑一个顶上吧
if result.IP == "" {
result.IP = "45.88.195.154"
}
FastIpCache = result.IP
return result.IP
}

View File

@@ -2,5 +2,5 @@ package util
//github action test 不支持v6 这里会报错
//func TestGetFastIP(t *testing.T) {
// GetFastIP("api.leo.moe", "443", true)
// GetFastIP("origin-fallback.nxtrace.org", "443", true)
//}

View File

@@ -2,6 +2,7 @@ package util
import (
"context"
"errors"
"fmt"
"github.com/nxtrace/NTrace-core/config"
"log"
@@ -21,6 +22,8 @@ var UserAgent = fmt.Sprintf("NextTrace %s/%s/%s", config.Version, runtime.GOOS,
var RdnsCache sync.Map
var PowProviderParam = ""
var DisableMPLS = GetenvDefault("NEXTTRACE_DISABLEMPLS", "")
var EnableHidDstIP = GetenvDefault("NEXTTRACE_ENABLEHIDDENDSTIP", "")
var DestIP string
func LookupAddr(addr string) ([]string, error) {
// 如果在缓存中找到,直接返回
@@ -75,7 +78,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
@@ -101,8 +104,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
@@ -119,16 +121,18 @@ func DomainLookUp(host string, ipVersion string, dotServer string, disableOutput
var filteredIPs []net.IP
for _, ip := range ips {
if ipVersion == "4" && ip.To4() != nil {
filteredIPs = append(filteredIPs, ip)
filteredIPs = []net.IP{ip}
break
} else if ipVersion == "6" && strings.Contains(ip.String(), ":") {
filteredIPs = append(filteredIPs, ip)
filteredIPs = []net.IP{ip}
break
}
}
ips = filteredIPs
}
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 {
@@ -147,7 +151,7 @@ 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
}
}
@@ -164,7 +168,7 @@ func GetenvDefault(key, defVal string) string {
}
func GetHostAndPort() (host string, port string) {
var hostP = GetenvDefault("NEXTTRACE_HOSTPORT", "api.leo.moe")
var hostP = GetenvDefault("NEXTTRACE_HOSTPORT", "origin-fallback.nxtrace.org")
// 解析域名
hostArr := strings.Split(hostP, ":")
// 判断是否有指定端口
@@ -204,9 +208,9 @@ func GetProxy() *url.URL {
}
func GetPowProvider() string {
var powProvider = ""
var powProvider string
if PowProviderParam == "" {
powProvider = GetenvDefault("NEXTTRACE_POWPROVIDER", "api.leo.moe")
powProvider = GetenvDefault("NEXTTRACE_POWPROVIDER", "api.nxtrace.org")
} else {
powProvider = PowProviderParam
}
@@ -224,3 +228,17 @@ func StringInSlice(val string, list []string) bool {
}
return false
}
func HideIPPart(ip string) string {
parsedIP := net.ParseIP(ip)
if parsedIP == nil {
return ""
}
if parsedIP.To4() != nil {
// IPv4: 隐藏后16位
return strings.Join(strings.Split(ip, ".")[:2], ".") + ".0.0/16"
}
// IPv6: 隐藏后96位
return parsedIP.Mask(net.CIDRMask(32, 128)).String() + "/32"
}

View File

@@ -10,6 +10,7 @@ import (
"net/url"
"os"
"os/signal"
"strings"
"sync"
"time"
@@ -188,7 +189,10 @@ func createWsConn() *WsConn {
// 如果 host 是一个 IP 使用默认域名
if valid := net.ParseIP(host); valid != nil {
fastIp = host
host = "api.leo.moe"
if len(strings.Split(fastIp, ":")) > 1 {
fastIp = "[" + fastIp + "]"
}
host = "origin-fallback.nxtrace.org"
} else {
// 默认配置完成,开始寻找最优 IP
fastIp = util.GetFastIP(host, port, true)