mirror of
https://github.com/nxtrace/NTrace-core.git
synced 2025-08-12 06:26:39 +00:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b2870a823f | ||
|
|
f82af5f9c5 | ||
|
|
9eda2d2a30 | ||
|
|
1a4a15eb74 | ||
|
|
f5556fea5d | ||
|
|
d760e75810 | ||
|
|
99409089b2 | ||
|
|
2040497d89 | ||
|
|
29ce61b24b | ||
|
|
701abc3447 | ||
|
|
f08778c862 | ||
|
|
8697325193 | ||
|
|
32b0f15e78 | ||
|
|
90e349eeed | ||
|
|
f275edba3a |
12
.github/workflows/build.yml
vendored
12
.github/workflows/build.yml
vendored
@@ -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,7 +124,10 @@ jobs:
|
||||
if [ "$GOOS" == "windows" ]; then
|
||||
export _NAME="$_NAME.exe"
|
||||
fi
|
||||
echo "GOOS: $GOOS, GOARCH: $GOARCH, GOARM: $GOARM, RELEASE_NAME: $_NAME"
|
||||
if [ "$GOMIPS" == "softfloat" ]; then
|
||||
export _NAME="${_NAME}_softfolat"
|
||||
fi
|
||||
echo "GOOS: $GOOS, GOARCH: $GOARCH, GOARM: $GOARM, GOMIPS: $GOMIPS, RELEASE_NAME: $_NAME"
|
||||
echo "ASSET_NAME=$_NAME" >> $GITHUB_ENV
|
||||
echo "BUILD_VERSION=$(git describe --tags --always)" >> $GITHUB_ENV
|
||||
echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV
|
||||
|
||||
15
README.md
15
README.md
@@ -47,6 +47,7 @@ We are extremely grateful to [DMIT](https://dmit.io) and [Misaka](https://misaka
|
||||
|
||||
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.
|
||||
@@ -141,7 +142,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
|
||||
|
||||
@@ -171,6 +172,17 @@ nexttrace --fast-trace
|
||||
|
||||
# You can also use TCP SYN for testing
|
||||
nexttrace --fast-trace --tcp
|
||||
|
||||
# You can also quickly test through a customized IP/DOMAIN list file
|
||||
nexttrace --file /path/to/your/iplist.txt
|
||||
# CUSTOMIZED IP DOMAIN LIST FILE FORMAT
|
||||
## One IP/DOMAIN per line + space + description information (optional)
|
||||
## forExample:
|
||||
## 106.37.67.1 BEIJING-TELECOM
|
||||
## 240e:928:101:31a::1 BEIJING-TELECOM
|
||||
## bj.10086.cn BEIJING-MOBILE
|
||||
## 2409:8080:0:1::1
|
||||
## 223.5.5.5
|
||||
```
|
||||
|
||||
`NextTrace` already supports route tracing for specified Network Devices
|
||||
@@ -369,6 +381,7 @@ Arguments:
|
||||
aliyun, dnspod, google, cloudflare]
|
||||
-g --language Choose the language for displaying [en,
|
||||
cn]. Default: cn
|
||||
--file Read IP Address or domain name from file
|
||||
```
|
||||
|
||||
## Project screenshot
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
|
||||
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的某个版本出现了严重的bug,NTrace-core会跳过这一有缺陷的版本,直接同步到下一个修复了该问题的版本。
|
||||
@@ -152,7 +153,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
|
||||
|
||||
@@ -182,6 +183,17 @@ nexttrace --fast-trace
|
||||
|
||||
# 也可以使用 TCP SYN 而非 ICMP 进行测试
|
||||
nexttrace --fast-trace --tcp
|
||||
|
||||
# 也可以通过自定义的IP/DOMAIN列表文件进行快速测试
|
||||
nexttrace --file /path/to/your/iplist.txt
|
||||
# 自定义的IP/DOMAIN列表文件格式
|
||||
## 一行一个IP/DOMAIN + 空格 + 描述信息(可选)
|
||||
## 例如:
|
||||
## 106.37.67.1 北京电信
|
||||
## 240e:928:101:31a::1 北京电信
|
||||
## bj.10086.cn 北京移动
|
||||
## 2409:8080:0:1::1
|
||||
## 223.5.5.5
|
||||
```
|
||||
|
||||
`NextTrace` 已支持指定网卡进行路由跟踪
|
||||
@@ -367,6 +379,7 @@ Arguments:
|
||||
aliyun, dnspod, google, cloudflare]
|
||||
-g --language Choose the language for displaying [en,
|
||||
cn]. Default: cn
|
||||
--file Read IP Address or domain name from file
|
||||
```
|
||||
|
||||
## 项目截图
|
||||
|
||||
19
cmd/cmd.go
19
cmd/cmd.go
@@ -69,6 +69,7 @@ func Excute() {
|
||||
Help: "Use DoT Server for DNS Parse [dnssb, aliyun, dnspod, google, cloudflare]"})
|
||||
lang := parser.Selector("g", "language", []string{"en", "cn"}, &argparse.Options{Default: "cn",
|
||||
Help: "Choose the language for displaying [en, cn]"})
|
||||
file := parser.String("", "file", &argparse.Options{Help: "Read IP Address or domain name from file"})
|
||||
|
||||
err := parser.Parse(os.Args)
|
||||
if err != nil {
|
||||
@@ -91,7 +92,7 @@ func Excute() {
|
||||
*port = 80
|
||||
}
|
||||
|
||||
if *fast_trace {
|
||||
if *fast_trace || *file != "" {
|
||||
var paramsFastTrace = fastTrace.ParamsFastTrace{
|
||||
SrcDev: *srcDev,
|
||||
SrcAddr: *srcAddr,
|
||||
@@ -102,6 +103,7 @@ func Excute() {
|
||||
Lang: *lang,
|
||||
PktSize: *packetSize,
|
||||
Timeout: time.Duration(*timeout) * time.Millisecond,
|
||||
File: *file,
|
||||
}
|
||||
|
||||
fastTrace.FastTest(*tcp, *output, paramsFastTrace)
|
||||
@@ -176,21 +178,26 @@ func Excute() {
|
||||
//
|
||||
//go func() {
|
||||
// defer wg.Done()
|
||||
err = nil
|
||||
if *udp {
|
||||
if *ipv6Only {
|
||||
fmt.Println("[Info] IPv6 UDP Traceroute is not supported right now.")
|
||||
os.Exit(0)
|
||||
}
|
||||
ip = util.DomainLookUp(domain, "4", *dot, *jsonPrint)
|
||||
ip, err = util.DomainLookUp(domain, "4", *dot, *jsonPrint)
|
||||
} else {
|
||||
if *ipv6Only {
|
||||
ip = util.DomainLookUp(domain, "6", *dot, *jsonPrint)
|
||||
ip, err = util.DomainLookUp(domain, "6", *dot, *jsonPrint)
|
||||
} else if *ipv4Only {
|
||||
ip = util.DomainLookUp(domain, "4", *dot, *jsonPrint)
|
||||
ip, err = util.DomainLookUp(domain, "4", *dot, *jsonPrint)
|
||||
} else {
|
||||
ip = util.DomainLookUp(domain, "all", *dot, *jsonPrint)
|
||||
ip, err = util.DomainLookUp(domain, "all", *dot, *jsonPrint)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
//}()
|
||||
//
|
||||
//wg.Wait()
|
||||
@@ -218,7 +225,7 @@ func Excute() {
|
||||
printer.PrintTraceRouteNav(ip, domain, *dataOrigin, *maxHops, *packetSize)
|
||||
}
|
||||
|
||||
var m trace.Method = ""
|
||||
var m trace.Method
|
||||
|
||||
switch {
|
||||
case *tcp:
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package fastTrace
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"github.com/nxtrace/NTrace-core/ipgeo"
|
||||
"github.com/nxtrace/NTrace-core/printer"
|
||||
@@ -12,6 +13,7 @@ import (
|
||||
"net"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -30,29 +32,25 @@ type ParamsFastTrace struct {
|
||||
Lang string
|
||||
PktSize int
|
||||
Timeout time.Duration
|
||||
File string
|
||||
}
|
||||
|
||||
type IpListElement struct {
|
||||
Ip string
|
||||
Desc string
|
||||
Version4 bool // true for IPv4, false for IPv6
|
||||
}
|
||||
|
||||
var oe = false
|
||||
|
||||
func (f *FastTracer) tracert(location string, ispCollection ISPCollection) {
|
||||
fp, err := os.OpenFile("/tmp/trace.log", os.O_CREATE|os.O_APPEND|os.O_RDWR, os.ModePerm)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer func(fp *os.File) {
|
||||
err := fp.Close()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}(fp)
|
||||
|
||||
log.SetOutput(fp)
|
||||
log.SetFlags(0)
|
||||
fmt.Printf("%s『%s %s 』%s\n", printer.YELLOW_PREFIX, location, ispCollection.ISPName, printer.RESET_PREFIX)
|
||||
log.Printf("『%s %s 』\n", location, ispCollection.ISPName)
|
||||
fmt.Printf("traceroute to %s, %d hops max, %d byte packets\n", ispCollection.IP, f.ParamsFastTrace.MaxHops, f.ParamsFastTrace.PktSize)
|
||||
log.Printf("traceroute to %s, %d hops max, %d byte packets\n", ispCollection.IP, f.ParamsFastTrace.MaxHops, f.ParamsFastTrace.PktSize)
|
||||
ip := util.DomainLookUp(ispCollection.IP, "4", "", true)
|
||||
|
||||
ip, err := util.DomainLookUp(ispCollection.IP, "4", "", true)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
var conf = trace.Config{
|
||||
BeginHop: f.ParamsFastTrace.BeginHop,
|
||||
DestIP: ip,
|
||||
@@ -72,6 +70,21 @@ func (f *FastTracer) tracert(location string, ispCollection ISPCollection) {
|
||||
}
|
||||
|
||||
if oe {
|
||||
fp, err := os.OpenFile("/tmp/trace.log", os.O_CREATE|os.O_APPEND|os.O_RDWR, os.ModePerm)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer func(fp *os.File) {
|
||||
err := fp.Close()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}(fp)
|
||||
|
||||
log.SetOutput(fp)
|
||||
log.SetFlags(0)
|
||||
log.Printf("『%s %s 』\n", location, ispCollection.ISPName)
|
||||
log.Printf("traceroute to %s, %d hops max, %d byte packets\n", ispCollection.IP, f.ParamsFastTrace.MaxHops, f.ParamsFastTrace.PktSize)
|
||||
conf.RealtimePrinter = tracelog.RealtimePrinter
|
||||
} else {
|
||||
conf.RealtimePrinter = printer.RealtimePrinter
|
||||
@@ -82,13 +95,19 @@ func (f *FastTracer) tracert(location string, ispCollection ISPCollection) {
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
println()
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
func FastTest(tm bool, outEnable bool, paramsFastTrace ParamsFastTrace) {
|
||||
// tm means tcp mode
|
||||
var c string
|
||||
pFastTrace := paramsFastTrace
|
||||
oe = outEnable
|
||||
|
||||
if paramsFastTrace.File != "" {
|
||||
testFile(paramsFastTrace, tm)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("Hi,欢迎使用 Fast Trace 功能,请注意 Fast Trace 功能只适合新手使用\n因为国内网络复杂,我们设置的测试目标有限,建议普通用户自测以获得更加精准的路由情况")
|
||||
fmt.Println("请您选择要测试的 IP 类型\n1. IPv4\n2. IPv6")
|
||||
fmt.Print("请选择选项:")
|
||||
@@ -97,16 +116,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 +164,7 @@ func FastTest(tm bool, outEnable bool, paramsFastTrace ParamsFastTrace) {
|
||||
}
|
||||
|
||||
ft := FastTracer{
|
||||
ParamsFastTrace: pFastTrace,
|
||||
ParamsFastTrace: paramsFastTrace,
|
||||
}
|
||||
|
||||
// 建立 WebSocket 连接
|
||||
@@ -156,6 +200,171 @@ 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.Printf("%s『%s』%s\n", printer.YELLOW_PREFIX, ip.Desc, printer.RESET_PREFIX)
|
||||
fmt.Printf("traceroute to %s, %d hops max, %d byte packets\n", ip.Ip, paramsFastTrace.MaxHops, paramsFastTrace.PktSize)
|
||||
var srcAddr string
|
||||
if ip.Version4 {
|
||||
if paramsFastTrace.SrcDev != "" {
|
||||
dev, _ := net.InterfaceByName(paramsFastTrace.SrcDev)
|
||||
if addrs, err := dev.Addrs(); err == nil {
|
||||
for _, addr := range addrs {
|
||||
if (addr.(*net.IPNet).IP.To4() == nil) == false {
|
||||
srcAddr = addr.(*net.IPNet).IP.String()
|
||||
// 检查是否是内网IP
|
||||
if !(net.ParseIP(srcAddr).IsPrivate() ||
|
||||
net.ParseIP(srcAddr).IsLoopback() ||
|
||||
net.ParseIP(srcAddr).IsLinkLocalUnicast() ||
|
||||
net.ParseIP(srcAddr).IsLinkLocalMulticast()) {
|
||||
// 若不是则跳出
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if paramsFastTrace.SrcDev != "" {
|
||||
dev, _ := net.InterfaceByName(paramsFastTrace.SrcDev)
|
||||
if addrs, err := dev.Addrs(); err == nil {
|
||||
for _, addr := range addrs {
|
||||
if (addr.(*net.IPNet).IP.To4() == nil) == true {
|
||||
srcAddr = addr.(*net.IPNet).IP.String()
|
||||
// 检查是否是内网IP
|
||||
if !(net.ParseIP(srcAddr).IsPrivate() ||
|
||||
net.ParseIP(srcAddr).IsLoopback() ||
|
||||
net.ParseIP(srcAddr).IsLinkLocalUnicast() ||
|
||||
net.ParseIP(srcAddr).IsLinkLocalMulticast()) {
|
||||
// 若不是则跳出
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var conf = trace.Config{
|
||||
BeginHop: paramsFastTrace.BeginHop,
|
||||
DestIP: net.ParseIP(ip.Ip),
|
||||
DestPort: 80,
|
||||
MaxHops: paramsFastTrace.MaxHops,
|
||||
NumMeasurements: 3,
|
||||
ParallelRequests: 18,
|
||||
RDns: paramsFastTrace.RDns,
|
||||
AlwaysWaitRDNS: paramsFastTrace.AlwaysWaitRDNS,
|
||||
PacketInterval: 100,
|
||||
TTLInterval: 500,
|
||||
IPGeoSource: ipgeo.GetSource("LeoMoeAPI"),
|
||||
Timeout: paramsFastTrace.Timeout,
|
||||
SrcAddr: srcAddr,
|
||||
PktSize: paramsFastTrace.PktSize,
|
||||
Lang: paramsFastTrace.Lang,
|
||||
}
|
||||
|
||||
if oe {
|
||||
fp, err := os.OpenFile("/tmp/trace.log", os.O_CREATE|os.O_APPEND|os.O_RDWR, os.ModePerm)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer func(fp *os.File) {
|
||||
err := fp.Close()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}(fp)
|
||||
|
||||
log.SetOutput(fp)
|
||||
log.SetFlags(0)
|
||||
log.Printf("『%s』\n", ip.Desc)
|
||||
log.Printf("traceroute to %s, %d hops max, %d byte packets\n", ip.Ip, paramsFastTrace.MaxHops, paramsFastTrace.PktSize)
|
||||
conf.RealtimePrinter = tracelog.RealtimePrinter
|
||||
} else {
|
||||
conf.RealtimePrinter = printer.RealtimePrinter
|
||||
}
|
||||
|
||||
_, err := trace.Traceroute(tracerouteMethod, conf)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (f *FastTracer) testAll() {
|
||||
f.testCT()
|
||||
println()
|
||||
|
||||
4
go.mod
4
go.mod
@@ -16,11 +16,11 @@ require (
|
||||
|
||||
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/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
|
||||
9
go.sum
9
go.sum
@@ -62,8 +62,8 @@ 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/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
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=
|
||||
@@ -151,8 +151,8 @@ 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-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.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
@@ -355,7 +355,6 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
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=
|
||||
|
||||
@@ -23,45 +23,56 @@ 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",
|
||||
sponsor()
|
||||
fmt.Fprintf(color.Output, "\n%s\n%s %s\n%s %s, %s, %s, %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"),
|
||||
//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", "Creator:"),
|
||||
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", "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", "Maintainer:"),
|
||||
color.New(color.FgHiBlue, color.Bold).Sprintf("%s", "Tso"),
|
||||
//color.New(color.FgHiBlack, color.Bold).Sprintf("%s", "tsosunchia@gmail.com"),
|
||||
)
|
||||
|
||||
moeQingOrgCopyRight()
|
||||
sponsor()
|
||||
//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"),
|
||||
fmt.Fprintf(color.Output, "%s\n%s %s, %s\n\n",
|
||||
color.New(color.FgCyan, color.Bold).Sprintf("%s", "NextTrace Project NOC"),
|
||||
color.New(color.FgWhite, color.Bold).Sprintf("%s", "MoeQing.io:"),
|
||||
color.New(color.FgHiBlue, color.Bold).Sprintf("%s", "YekongTAT"),
|
||||
//color.New(color.FgHiBlack, color.Bold).Sprintf("%s", "yekongtat@gmail.com"),
|
||||
color.New(color.FgHiBlue, 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", "· Skywolf.cloud"),
|
||||
color.New(color.FgHiBlack, color.Bold).Sprintf("%s", formatted),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,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 {
|
||||
@@ -164,6 +165,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 +180,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()
|
||||
|
||||
|
||||
@@ -30,7 +30,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 +44,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)
|
||||
}
|
||||
}
|
||||
@@ -78,6 +78,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()
|
||||
@@ -189,6 +190,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 +235,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()
|
||||
|
||||
|
||||
@@ -257,7 +257,7 @@ func (t *TCPTracer) send(ttl int) error {
|
||||
t.inflightRequest[int(sequenceNumber)] = hopCh
|
||||
t.inflightRequestLock.Unlock()
|
||||
/*
|
||||
// 这里属于 2个Sender,N个Reciever的情况,在哪里关闭Channel都容易导致Panic
|
||||
// 这里属于 2个Sender,N个Receiver的情况,在哪里关闭Channel都容易导致Panic
|
||||
defer func() {
|
||||
t.inflightRequestLock.Lock()
|
||||
close(hopCh)
|
||||
|
||||
@@ -141,7 +141,7 @@ func (h *Hop) fetchIPData(c Config) (err error) {
|
||||
h.Hostname = r[0][:len(r[0])-1]
|
||||
ip = h.Address.String() + "," + h.Hostname
|
||||
}
|
||||
h.Geo, err = c.IPGeoSource(ip, c.Timeout, c.Lang, c.Maptrace)
|
||||
h.Geo, _ = c.IPGeoSource(ip, c.Timeout, c.Lang, c.Maptrace)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -221,9 +221,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
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,10 @@ func GetMapUrl(r string) (string, error) {
|
||||
fastIp := "api.leo.moe"
|
||||
// 如果 host 是一个 IP 使用默认域名
|
||||
if valid := net.ParseIP(host); valid != nil {
|
||||
fastIp = host
|
||||
if len(strings.Split(fastIp, ":")) > 1 {
|
||||
fastIp = "[" + fastIp + "]"
|
||||
}
|
||||
host = "api.leo.moe"
|
||||
} else {
|
||||
// 默认配置完成,开始寻找最优 IP
|
||||
|
||||
@@ -13,8 +13,8 @@ func TestDNS(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDomainLookUp(t *testing.T) {
|
||||
ips := DomainLookUp("pek-4134.nexttrace-io-fasttrace-endpoint.win.", "all", "", false)
|
||||
ips, _ := DomainLookUp("pek-4134.nexttrace-io-fasttrace-endpoint.win.", "all", "", false)
|
||||
fmt.Println(ips)
|
||||
ips = DomainLookUp("pek-4134.nexttrace-io-fasttrace-endpoint.win.", "4", "", false)
|
||||
ips, _ = DomainLookUp("pek-4134.nexttrace-io-fasttrace-endpoint.win.", "4", "", false)
|
||||
fmt.Println(ips)
|
||||
}
|
||||
|
||||
@@ -60,7 +60,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),
|
||||
|
||||
16
util/util.go
16
util/util.go
@@ -2,6 +2,7 @@ package util
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/nxtrace/NTrace-core/config"
|
||||
"log"
|
||||
@@ -75,7 +76,7 @@ func LocalIPPortv6(dstip net.IP) (net.IP, int) {
|
||||
return nil, -1
|
||||
}
|
||||
|
||||
func DomainLookUp(host string, ipVersion string, dotServer string, disableOutput bool) net.IP {
|
||||
func DomainLookUp(host string, ipVersion string, dotServer string, disableOutput bool) (net.IP, error) {
|
||||
// ipVersion: 4, 6, all
|
||||
var (
|
||||
r *net.Resolver
|
||||
@@ -101,8 +102,7 @@ func DomainLookUp(host string, ipVersion string, dotServer string, disableOutput
|
||||
ips = append(ips, net.ParseIP(v))
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Println("Domain " + host + " Lookup Fail.")
|
||||
os.Exit(1)
|
||||
return nil, errors.New("DNS lookup failed")
|
||||
}
|
||||
|
||||
//var ipv6Flag = false
|
||||
@@ -119,16 +119,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 +149,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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"net/url"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -188,6 +189,9 @@ func createWsConn() *WsConn {
|
||||
// 如果 host 是一个 IP 使用默认域名
|
||||
if valid := net.ParseIP(host); valid != nil {
|
||||
fastIp = host
|
||||
if len(strings.Split(fastIp, ":")) > 1 {
|
||||
fastIp = "[" + fastIp + "]"
|
||||
}
|
||||
host = "api.leo.moe"
|
||||
} else {
|
||||
// 默认配置完成,开始寻找最优 IP
|
||||
|
||||
Reference in New Issue
Block a user