Compare commits

...

11 Commits

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

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-11 23:17:18 +00:00
13 changed files with 354 additions and 89 deletions

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

View File

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

View File

@@ -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的某个版本出现了严重的bugNTrace-core会跳过这一有缺陷的版本直接同步到下一个修复了该问题的版本。
@@ -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
```
## 项目截图

View File

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

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,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()

2
go.mod
View File

@@ -10,7 +10,7 @@ require (
github.com/stretchr/testify v1.8.4
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635
github.com/tsosunchia/powclient v0.1.4
golang.org/x/net v0.16.0
golang.org/x/net v0.17.0
golang.org/x/sync v0.4.0
)

4
go.sum
View File

@@ -296,8 +296,8 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.16.0 h1:7eBu7KsSvFDtSXUIDbh3aqlK4DPsZ1rByC8PFfBThos=
golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
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=

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

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

View File

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

View File

@@ -21,6 +21,7 @@ type ResponseInfo struct {
var (
results = make(chan ResponseInfo)
timeout = 5 * time.Second
)
var FastIpCache = ""
@@ -38,6 +39,11 @@ func GetFastIP(domain string, port string, enableOutput bool) string {
log.Fatal("DNS resolution failed, please check your system DNS Settings")
}
if len(ips) == 0 {
// 添加默认IP 45.88.195.154
ips = append(ips, net.ParseIP("45.88.195.154"))
}
for _, ip := range ips {
go checkLatency(domain, ip.String(), port)
}
@@ -46,21 +52,22 @@ func GetFastIP(domain string, port string, enableOutput bool) string {
select {
case result = <-results:
case <-time.After(1 * time.Second):
log.Fatal("IP connection has been timeout, please check your network")
//等待5s没有结果 视为连不上API了
case <-time.After(timeout):
log.Println("IP connection has been timeout, please check your network")
}
if len(ips) > 0 {
if enableOutput {
_, _ = fmt.Fprintf(color.Output, "%s prefered API IP - %s - %s - %s",
color.New(color.FgWhite, color.Bold).Sprintf("[NextTrace API]"),
color.New(color.FgGreen, color.Bold).Sprintf("%s", result.IP),
color.New(color.FgCyan, color.Bold).Sprintf("%sms", result.Latency),
color.New(color.FgGreen, color.Bold).Sprintf("%s", result.Content),
)
}
//if len(ips) > 0 {
if enableOutput {
_, _ = fmt.Fprintf(color.Output, "%s preferred API IP - %s - %s - %s",
color.New(color.FgWhite, color.Bold).Sprintf("[NextTrace API]"),
color.New(color.FgGreen, color.Bold).Sprintf("%s", result.IP),
color.New(color.FgCyan, color.Bold).Sprintf("%sms", result.Latency),
color.New(color.FgGreen, color.Bold).Sprintf("%s", result.Content),
)
}
//}
FastIpCache = result.IP
return result.IP
}
@@ -79,31 +86,32 @@ func checkLatency(domain string, ip string, port string) {
TLSClientConfig: &tls.Config{
ServerName: domain,
},
TLSHandshakeTimeout: 1 * time.Second,
TLSHandshakeTimeout: timeout,
}
client := &http.Client{
Transport: transport,
Timeout: 2 * time.Second,
Timeout: timeout,
}
//此处虽然是 https://domain/ 但是实际上会使用指定的IP连接
req, err := http.NewRequest("GET", "https://"+ip+":"+port+"/", nil)
if err != nil {
results <- ResponseInfo{IP: ip, Latency: "error", Content: ""}
// !!! 此处不要给results返回任何值
//results <- ResponseInfo{IP: ip, Latency: "error", Content: ""}
return
}
req.Host = domain
resp, err := client.Do(req)
if err != nil {
results <- ResponseInfo{IP: ip, Latency: "error", Content: ""}
//results <- ResponseInfo{IP: ip, Latency: "error", Content: ""}
return
}
defer resp.Body.Close()
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
results <- ResponseInfo{IP: ip, Latency: "error", Content: ""}
//results <- ResponseInfo{IP: ip, Latency: "error", Content: ""}
return
}
bodyString := string(bodyBytes)

View File

@@ -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
@@ -128,7 +128,7 @@ func DomainLookUp(host string, ipVersion string, dotServer string, disableOutput
}
if (len(ips) == 1) || (disableOutput) {
return ips[0]
return ips[0], nil
} else {
fmt.Println("Please Choose the IP You Want To TraceRoute")
for i, ip := range ips {
@@ -147,7 +147,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
}
}