重构关于地理位置以及 PTR 记录获取的模块,大幅提升路由跟踪性能

This commit is contained in:
Leo
2023-02-01 18:22:02 +08:00
parent c8077919ce
commit cc1d6177ca
3 changed files with 96 additions and 26 deletions

View File

@@ -38,7 +38,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{"IP.SB", "IPInfo", "IPInsight", "IPAPI.com"}, &argparse.Options{Default: "LeoMoeAPI",
Help: "Choose IP Geograph Data Provider [LeoMoeAPI,IP.SB, IPInfo, IPInsight, IPAPI.com]"})
noRdns := parser.Flag("n", "no-rdns", &argparse.Options{Help: " Do not resolve IP addresses to their domain names"})
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"})
report := parser.Flag("r", "report", &argparse.Options{Help: "output using report mode"})
output := parser.Flag("o", "output", &argparse.Options{Help: "Write trace result to file (RealTimePrinter ONLY)"})
@@ -50,8 +51,8 @@ func Excute() {
src_addr := parser.String("s", "source", &argparse.Options{Help: "Use source src_addr for outgoing packets"})
src_dev := 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]"})
packet_interval := parser.Int("z", "send-time", &argparse.Options{Default: 100, Help: "Set the time interval for sending every packet. Useful when some routers use rate-limit for ICMP messages."})
ttl_interval := parser.Int("i", "ttl-time", &argparse.Options{Default: 500, Help: "Set the time interval for sending packets groups by TTL. Useful when some routers use rate-limit for ICMP messages."})
packet_interval := parser.Int("z", "send-time", &argparse.Options{Default: 100, Help: "Set the time interval for sending every packet. Useful when some routers use rate-limit for ICMP messages"})
ttl_interval := parser.Int("i", "ttl-time", &argparse.Options{Default: 500, Help: "Set the time interval for sending packets groups by TTL. Useful when some routers use rate-limit for ICMP messages"})
str := parser.StringPositional(&argparse.Options{Help: "IP Address or domain name"})
err := parser.Parse(os.Args)
@@ -151,6 +152,7 @@ func Excute() {
NumMeasurements: *numMeasurements,
ParallelRequests: *parallelRequests,
RDns: !*noRdns,
AlwaysWaitRDNS: *alwaysRdns,
IPGeoSource: ipgeo.GetSource(*dataOrigin),
Timeout: 1 * time.Second,
}

View File

@@ -21,7 +21,44 @@ func Version() {
}
func CopyRight() {
fmt.Println("XGadget-lab Leo (leo.moe) & Tso (tsosunchia@gmail.com) & Vincent (vincent.moe) & zhshch (xzhsh.ch)")
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()
PluginCopyRight()
}
func MoeQingOrgCopyRight() {
fmt.Fprintf(color.Output, "%s\n%s %s\n%s %s\n\n",
color.New(color.FgHiYellow, color.Bold).Sprintf("%s", "MoeQing Network"),
color.New(color.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 PluginCopyRight() {
fmt.Fprintf(color.Output, "%s\n%s %s\n\n",
color.New(color.FgGreen, color.Bold).Sprintf("%s", "NextTrace Map Plugin Author"),
color.New(color.FgWhite, color.Bold).Sprintf("%s", "Tso"),
color.New(color.FgHiBlack, color.Bold).Sprintf("%s", "tsosunchia@gmail.com"),
)
}
func PrintTraceRouteNav(ip net.IP, domain string, dataOrigin string) {

View File

@@ -2,9 +2,7 @@ package trace
import (
"errors"
"github.com/xgadget-lab/nexttrace/util"
"net"
"os"
"sync"
"time"
@@ -29,6 +27,7 @@ type Config struct {
Quic bool
IPGeoSource ipgeo.Source
RDns bool
AlwaysWaitRDNS bool
PacketInterval int
TTLInterval int
RealtimePrinter func(res *Result, ttl int)
@@ -120,40 +119,72 @@ type Hop struct {
}
func (h *Hop) fetchIPData(c Config) (err error) {
if c.RDns {
var rdnsENV = util.GetenvDefault("NEXTTRACE_RDNS", "1")
if rdnsENV != "1" {
c.RDns = false
}
}
timeout := time.Millisecond * 2400
// Debug Area
// c.AlwaysWaitRDNS = true
// Initialize a rDNS Channel
rDNSChan := make(chan []string)
fetchDoneChan := make(chan bool)
if c.RDns && h.Hostname == "" {
result := make(chan []string)
// Create a rDNS Query go-routine
go func() {
r, err := net.LookupAddr(h.Address.String())
if err != nil {
result <- nil
// No PTR Record
rDNSChan <- nil
} else {
result <- r
// One PTR Record is found
rDNSChan <- r
}
}()
}
// Create Data Fetcher go-routine
go func() {
// Start to fetch IP Geolocation data
if c.IPGeoSource != nil && h.Geo == nil {
res := false
h.Geo, res = ipgeo.Filter(h.Address.String())
if !res {
h.Geo, err = c.IPGeoSource(h.Address.String())
}
}
// Fetch Done
fetchDoneChan <- true
}()
// Select Close Flag
var selectClose bool
if !c.AlwaysWaitRDNS {
select {
case ptr := <-result:
case <-fetchDoneChan:
// When fetch done signal recieved, stop waiting PTR record
case ptr := <-rDNSChan:
// process result
if err == nil && len(ptr) > 0 {
h.Hostname = ptr[0][:len(ptr[0])-1]
}
selectClose = true
}
} else {
select {
case ptr := <-rDNSChan:
// process result
if err == nil && len(ptr) > 0 {
h.Hostname = ptr[0]
}
case <-time.After(timeout):
// handle timeout
_ = os.Setenv("NEXTTRACE_RDNS", "0")
// 1 second timeout
case <-time.After(time.Second * 1):
}
selectClose = true
}
if c.IPGeoSource != nil && h.Geo == nil {
res := false
h.Geo, res = ipgeo.Filter(h.Address.String())
if !res {
h.Geo, err = c.IPGeoSource(h.Address.String())
}
// When Select Close, fetchDoneChan Reciever will also be closed
if selectClose {
// New a reciever to prevent channel congestion
<-fetchDoneChan
}
return
}