mirror of
https://github.com/oneclickvirt/backtrace.git
synced 2025-04-21 19:52:07 +08:00
feat: 结构化IPV4和IPV6的代码
This commit is contained in:
parent
f1ccde0ea9
commit
a832d354da
95
bk/asn.go
95
bk/asn.go
@ -1,95 +0,0 @@
|
|||||||
package backtrace
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Result struct {
|
|
||||||
i int
|
|
||||||
s string
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
ipv4s = []string{
|
|
||||||
// "219.141.136.12", "202.106.50.1",
|
|
||||||
"219.141.140.10", "202.106.195.68", "221.179.155.161",
|
|
||||||
"202.96.209.133", "210.22.97.1", "211.136.112.200",
|
|
||||||
"58.60.188.222", "210.21.196.6", "120.196.165.24",
|
|
||||||
"61.139.2.69", "119.6.6.6", "211.137.96.205",
|
|
||||||
}
|
|
||||||
ipv4Names = []string{
|
|
||||||
"北京电信v4", "北京联通v4", "北京移动v4",
|
|
||||||
"上海电信v4", "上海联通v4", "上海移动v4",
|
|
||||||
"广州电信v4", "广州联通v4", "广州移动v4",
|
|
||||||
"成都电信v4", "成都联通v4", "成都移动v4",
|
|
||||||
}
|
|
||||||
ipv6s = []string{
|
|
||||||
"2400:89c0:1053:3::69", // 北京电信 IPv6
|
|
||||||
"2400:89c0:1013:3::54", // 北京联通 IPv6
|
|
||||||
"2409:8c00:8421:1303::55", // 北京移动 IPv6
|
|
||||||
"240e:e1:aa00:4000::24", // 上海电信 IPV6
|
|
||||||
"2408:80f1:21:5003::a", // 上海联通 IPv6
|
|
||||||
"2409:8c1e:75b0:3003::26", // 上海移动 IPv6
|
|
||||||
"240e:97c:2f:3000::44", // 广州电信 IPv6
|
|
||||||
"2408:8756:f50:1001::c", // 广州联通 IPv6
|
|
||||||
"2409:8c54:871:1001::12", // 广州移动 IPv6
|
|
||||||
}
|
|
||||||
ipv6Names = []string{
|
|
||||||
"北京电信v6", "北京联通v6", "北京移动v6",
|
|
||||||
"上海电信v6", "上海联通v6", "上海移动v6",
|
|
||||||
"广州电信v6", "广州联通v6", "广州移动v6",
|
|
||||||
}
|
|
||||||
m = map[string]string{
|
|
||||||
// [] 前的字符串个数,中文占2个字符串
|
|
||||||
"AS23764": "电信CTGNET [精品线路]",
|
|
||||||
"AS4809a": "电信CN2GIA [精品线路]",
|
|
||||||
"AS4809b": "电信CN2GT [优质线路]",
|
|
||||||
"AS4809": "电信CN2 [优质线路]",
|
|
||||||
"AS4134": "电信163 [普通线路]",
|
|
||||||
"AS9929": "联通9929 [优质线路]",
|
|
||||||
"AS4837": "联通4837 [普通线路]",
|
|
||||||
"AS58807": "移动CMIN2 [精品线路]",
|
|
||||||
"AS9808": "移动CMI [普通线路]",
|
|
||||||
"AS58453": "移动CMI [普通线路]",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func removeDuplicates(elements []string) []string {
|
|
||||||
encountered := map[string]bool{} // 用于存储已经遇到的元素
|
|
||||||
result := []string{} // 存储去重后的结果
|
|
||||||
for v := range elements { // 遍历切片中的元素
|
|
||||||
if encountered[elements[v]] == true { // 如果该元素已经遇到过
|
|
||||||
// 存在过就不加入了
|
|
||||||
} else {
|
|
||||||
encountered[elements[v]] = true // 将该元素标记为已经遇到
|
|
||||||
result = append(result, elements[v]) // 将该元素加入到结果切片中
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result // 返回去重后的结果切片
|
|
||||||
}
|
|
||||||
|
|
||||||
func ipAsn(ip string) string {
|
|
||||||
if strings.Contains(ip, ":") {
|
|
||||||
return ipv6Asn(ip)
|
|
||||||
}
|
|
||||||
switch {
|
|
||||||
case strings.HasPrefix(ip, "59.43"):
|
|
||||||
return "AS4809"
|
|
||||||
case strings.HasPrefix(ip, "202.97"):
|
|
||||||
return "AS4134"
|
|
||||||
case strings.HasPrefix(ip, "218.105") || strings.HasPrefix(ip, "210.51"):
|
|
||||||
return "AS9929"
|
|
||||||
case strings.HasPrefix(ip, "219.158"):
|
|
||||||
return "AS4837"
|
|
||||||
case strings.HasPrefix(ip, "223.120.19") || strings.HasPrefix(ip, "223.120.17") || strings.HasPrefix(ip, "223.120.16") ||
|
|
||||||
strings.HasPrefix(ip, "223.120.140") || strings.HasPrefix(ip, "223.120.130") || strings.HasPrefix(ip, "223.120.131") ||
|
|
||||||
strings.HasPrefix(ip, "223.120.141"):
|
|
||||||
return "AS58807"
|
|
||||||
case strings.HasPrefix(ip, "223.118") || strings.HasPrefix(ip, "223.119") || strings.HasPrefix(ip, "223.120") || strings.HasPrefix(ip, "223.121"):
|
|
||||||
return "AS58453"
|
|
||||||
case strings.HasPrefix(ip, "69.194") || strings.HasPrefix(ip, "203.22"):
|
|
||||||
return "AS23764"
|
|
||||||
default:
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,22 +3,24 @@ package backtrace
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/oneclickvirt/backtrace/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
func BackTrace(test bool) {
|
func BackTrace(test bool) {
|
||||||
if test {
|
if test {
|
||||||
ipv4Count := len(ipv4s)
|
ipv4Count := len(model.Ipv4s)
|
||||||
ipv6Count := len(ipv6s)
|
ipv6Count := len(model.Ipv6s)
|
||||||
totalCount := ipv4Count + ipv6Count
|
totalCount := ipv4Count + ipv6Count
|
||||||
var (
|
var (
|
||||||
s = make([]string, totalCount)
|
s = make([]string, totalCount)
|
||||||
c = make(chan Result)
|
c = make(chan Result)
|
||||||
t = time.After(time.Second * 10)
|
t = time.After(time.Second * 10)
|
||||||
)
|
)
|
||||||
for i := range ipv4s {
|
for i := range model.Ipv4s {
|
||||||
go trace(c, i)
|
go trace(c, i)
|
||||||
}
|
}
|
||||||
for i := range ipv6s {
|
for i := range model.Ipv6s {
|
||||||
go traceIPv6(c, i, ipv4Count)
|
go traceIPv6(c, i, ipv4Count)
|
||||||
}
|
}
|
||||||
loopIPv4v6:
|
loopIPv4v6:
|
||||||
@ -41,13 +43,13 @@ func BackTrace(test bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ipCount := len(ipv4s)
|
ipCount := len(model.Ipv4s)
|
||||||
var (
|
var (
|
||||||
s = make([]string, ipCount)
|
s = make([]string, ipCount)
|
||||||
c = make(chan Result)
|
c = make(chan Result)
|
||||||
t = time.After(time.Second * 10)
|
t = time.After(time.Second * 10)
|
||||||
)
|
)
|
||||||
for i := range ipv4s {
|
for i := range model.Ipv4s {
|
||||||
go trace(c, i)
|
go trace(c, i)
|
||||||
}
|
}
|
||||||
loopIPv4:
|
loopIPv4:
|
||||||
|
31
bk/ipv4_asn.go
Normal file
31
bk/ipv4_asn.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package backtrace
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ipv4Asn(ip string) string {
|
||||||
|
if strings.Contains(ip, ":") {
|
||||||
|
return ipv6Asn(ip)
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case strings.HasPrefix(ip, "59.43"):
|
||||||
|
return "AS4809"
|
||||||
|
case strings.HasPrefix(ip, "202.97"):
|
||||||
|
return "AS4134"
|
||||||
|
case strings.HasPrefix(ip, "218.105") || strings.HasPrefix(ip, "210.51"):
|
||||||
|
return "AS9929"
|
||||||
|
case strings.HasPrefix(ip, "219.158"):
|
||||||
|
return "AS4837"
|
||||||
|
case strings.HasPrefix(ip, "223.120.19") || strings.HasPrefix(ip, "223.120.17") || strings.HasPrefix(ip, "223.120.16") ||
|
||||||
|
strings.HasPrefix(ip, "223.120.140") || strings.HasPrefix(ip, "223.120.130") || strings.HasPrefix(ip, "223.120.131") ||
|
||||||
|
strings.HasPrefix(ip, "223.120.141"):
|
||||||
|
return "AS58807"
|
||||||
|
case strings.HasPrefix(ip, "223.118") || strings.HasPrefix(ip, "223.119") || strings.HasPrefix(ip, "223.120") || strings.HasPrefix(ip, "223.121"):
|
||||||
|
return "AS58453"
|
||||||
|
case strings.HasPrefix(ip, "69.194") || strings.HasPrefix(ip, "203.22"):
|
||||||
|
return "AS23764"
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
@ -7,34 +7,35 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/oneclickvirt/backtrace/model"
|
||||||
. "github.com/oneclickvirt/defaultset"
|
. "github.com/oneclickvirt/defaultset"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (t *Tracer) listen(network string, laddr *net.IPAddr) (*net.IPConn, error) {
|
func (t *Tracer) listen(network string, laddr *net.IPAddr) (*net.IPConn, error) {
|
||||||
conn, err := net.ListenIP(network, laddr)
|
conn, err := net.ListenIP(network, laddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(err.Error())
|
Logger.Info(err.Error())
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
raw, err := conn.SyscallConn()
|
raw, err := conn.SyscallConn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(err.Error())
|
Logger.Info(err.Error())
|
||||||
}
|
}
|
||||||
conn.Close()
|
conn.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
_ = raw.Control(func(fd uintptr) {
|
_ = raw.Control(func(fd uintptr) {
|
||||||
err = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_HDRINCL, 1)
|
err = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_HDRINCL, 1)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(err.Error())
|
Logger.Info(err.Error())
|
||||||
}
|
}
|
||||||
conn.Close()
|
conn.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return conn, nil
|
return conn, nil
|
||||||
}
|
}
|
||||||
|
@ -7,24 +7,25 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/oneclickvirt/backtrace/model"
|
||||||
. "github.com/oneclickvirt/defaultset"
|
. "github.com/oneclickvirt/defaultset"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (t *Tracer) listen(network string, laddr *net.IPAddr) (*net.IPConn, error) {
|
func (t *Tracer) listen(network string, laddr *net.IPAddr) (*net.IPConn, error) {
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
InitLogger()
|
InitLogger()
|
||||||
defer Logger.Sync()
|
defer Logger.Sync()
|
||||||
}
|
}
|
||||||
conn, err := net.ListenIP(network, laddr)
|
conn, err := net.ListenIP(network, laddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(err.Error())
|
Logger.Info(err.Error())
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
raw, err := conn.SyscallConn()
|
raw, err := conn.SyscallConn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(err.Error())
|
Logger.Info(err.Error())
|
||||||
}
|
}
|
||||||
conn.Close()
|
conn.Close()
|
||||||
@ -34,7 +35,7 @@ func (t *Tracer) listen(network string, laddr *net.IPAddr) (*net.IPConn, error)
|
|||||||
err = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_HDRINCL, 1)
|
err = syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_HDRINCL, 1)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(err.Error())
|
Logger.Info(err.Error())
|
||||||
}
|
}
|
||||||
conn.Close()
|
conn.Close()
|
||||||
|
@ -6,39 +6,40 @@ package backtrace
|
|||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
|
"github.com/oneclickvirt/backtrace/model"
|
||||||
. "github.com/oneclickvirt/defaultset"
|
. "github.com/oneclickvirt/defaultset"
|
||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (t *Tracer) listen(network string, laddr *net.IPAddr) (*net.IPConn, error) {
|
func (t *Tracer) listen(network string, laddr *net.IPAddr) (*net.IPConn, error) {
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
InitLogger()
|
InitLogger()
|
||||||
defer Logger.Sync()
|
defer Logger.Sync()
|
||||||
}
|
}
|
||||||
conn, err := net.ListenIP(network, laddr)
|
conn, err := net.ListenIP(network, laddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(err.Error())
|
Logger.Info(err.Error())
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
raw, err := conn.SyscallConn()
|
raw, err := conn.SyscallConn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(err.Error())
|
Logger.Info(err.Error())
|
||||||
}
|
}
|
||||||
conn.Close()
|
conn.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
_ = raw.Control(func(fd uintptr) {
|
_ = raw.Control(func(fd uintptr) {
|
||||||
err = windows.SetsockoptInt(windows.Handle(fd), windows.IPPROTO_IP, windows.IP_HDRINCL, 1)
|
err = windows.SetsockoptInt(windows.Handle(fd), windows.IPPROTO_IP, windows.IP_HDRINCL, 1)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(err.Error())
|
Logger.Info(err.Error())
|
||||||
}
|
}
|
||||||
conn.Close()
|
conn.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return conn, nil
|
return conn, nil
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/oneclickvirt/backtrace/model"
|
||||||
. "github.com/oneclickvirt/defaultset"
|
. "github.com/oneclickvirt/defaultset"
|
||||||
"golang.org/x/net/icmp"
|
"golang.org/x/net/icmp"
|
||||||
"golang.org/x/net/ipv4"
|
"golang.org/x/net/ipv4"
|
||||||
@ -136,7 +137,7 @@ func (t *Tracer) init() {
|
|||||||
t.ipv6conn = ipv6.NewPacketConn(conn)
|
t.ipv6conn = ipv6.NewPacketConn(conn)
|
||||||
err = t.ipv6conn.SetControlMessage(ipv6.FlagHopLimit|ipv6.FlagSrc|ipv6.FlagDst|ipv6.FlagInterface, true)
|
err = t.ipv6conn.SetControlMessage(ipv6.FlagHopLimit|ipv6.FlagSrc|ipv6.FlagDst|ipv6.FlagInterface, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
InitLogger()
|
InitLogger()
|
||||||
defer Logger.Sync()
|
defer Logger.Sync()
|
||||||
Logger.Info("设置IPv6控制消息失败: " + err.Error())
|
Logger.Info("设置IPv6控制消息失败: " + err.Error())
|
||||||
@ -183,19 +184,19 @@ func (t *Tracer) serveData(from net.IP, b []byte) error {
|
|||||||
// IPv6处理
|
// IPv6处理
|
||||||
msg, err := icmp.ParseMessage(ProtocolIPv6ICMP, b)
|
msg, err := icmp.ParseMessage(ProtocolIPv6ICMP, b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Warn("解析IPv6 ICMP消息失败: " + err.Error())
|
Logger.Warn("解析IPv6 ICMP消息失败: " + err.Error())
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// 记录所有收到的消息类型,帮助调试
|
// 记录所有收到的消息类型,帮助调试
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(fmt.Sprintf("收到IPv6 ICMP消息: 类型=%v, 代码=%v", msg.Type, msg.Code))
|
Logger.Info(fmt.Sprintf("收到IPv6 ICMP消息: 类型=%v, 代码=%v", msg.Type, msg.Code))
|
||||||
}
|
}
|
||||||
// 处理不同类型的ICMP消息
|
// 处理不同类型的ICMP消息
|
||||||
if msg.Type == ipv6.ICMPTypeEchoReply {
|
if msg.Type == ipv6.ICMPTypeEchoReply {
|
||||||
if echo, ok := msg.Body.(*icmp.Echo); ok {
|
if echo, ok := msg.Body.(*icmp.Echo); ok {
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(fmt.Sprintf("处理IPv6回显应答: ID=%d, Seq=%d", echo.ID, echo.Seq))
|
Logger.Info(fmt.Sprintf("处理IPv6回显应答: ID=%d, Seq=%d", echo.ID, echo.Seq))
|
||||||
}
|
}
|
||||||
return t.serveReply(from, &packet{from, uint16(echo.ID), 1, time.Now()})
|
return t.serveReply(from, &packet{from, uint16(echo.ID), 1, time.Now()})
|
||||||
@ -203,7 +204,7 @@ func (t *Tracer) serveData(from net.IP, b []byte) error {
|
|||||||
} else if msg.Type == ipv6.ICMPTypeTimeExceeded {
|
} else if msg.Type == ipv6.ICMPTypeTimeExceeded {
|
||||||
b = getReplyData(msg)
|
b = getReplyData(msg)
|
||||||
if len(b) < ipv6.HeaderLen {
|
if len(b) < ipv6.HeaderLen {
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Warn("IPv6时间超过消息太短")
|
Logger.Warn("IPv6时间超过消息太短")
|
||||||
}
|
}
|
||||||
return errMessageTooShort
|
return errMessageTooShort
|
||||||
@ -212,12 +213,12 @@ func (t *Tracer) serveData(from net.IP, b []byte) error {
|
|||||||
if b[0]>>4 == ipv6.Version {
|
if b[0]>>4 == ipv6.Version {
|
||||||
ip, err := ipv6.ParseHeader(b)
|
ip, err := ipv6.ParseHeader(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Warn("解析IPv6头部失败: " + err.Error())
|
Logger.Warn("解析IPv6头部失败: " + err.Error())
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(fmt.Sprintf("处理IPv6时间超过: 目标=%v, FlowLabel=%d, HopLimit=%d",
|
Logger.Info(fmt.Sprintf("处理IPv6时间超过: 目标=%v, FlowLabel=%d, HopLimit=%d",
|
||||||
ip.Dst, ip.FlowLabel, ip.HopLimit))
|
ip.Dst, ip.FlowLabel, ip.HopLimit))
|
||||||
}
|
}
|
||||||
@ -265,7 +266,7 @@ func (t *Tracer) sendRequest(dst net.IP, ttl int) (*packet, error) {
|
|||||||
}
|
}
|
||||||
_, err := t.ipv6conn.WriteTo(b, cm, &net.IPAddr{IP: dst})
|
_, err := t.ipv6conn.WriteTo(b, cm, &net.IPAddr{IP: dst})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
InitLogger()
|
InitLogger()
|
||||||
defer Logger.Sync()
|
defer Logger.Sync()
|
||||||
Logger.Info("发送IPv6请求失败: " + err.Error())
|
Logger.Info("发送IPv6请求失败: " + err.Error())
|
||||||
@ -308,7 +309,7 @@ func (t *Tracer) removeSession(s *Session) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Tracer) serveReply(dst net.IP, res *packet) error {
|
func (t *Tracer) serveReply(dst net.IP, res *packet) error {
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(fmt.Sprintf("处理回复: 目标=%v, 来源=%v, ID=%d, TTL=%d",
|
Logger.Info(fmt.Sprintf("处理回复: 目标=%v, 来源=%v, ID=%d, TTL=%d",
|
||||||
dst, res.IP, res.ID, res.TTL))
|
dst, res.IP, res.ID, res.TTL))
|
||||||
}
|
}
|
||||||
@ -317,7 +318,7 @@ func (t *Tracer) serveReply(dst net.IP, res *packet) error {
|
|||||||
t.mu.RLock()
|
t.mu.RLock()
|
||||||
defer t.mu.RUnlock()
|
defer t.mu.RUnlock()
|
||||||
// // 调试输出会话信息
|
// // 调试输出会话信息
|
||||||
// if EnableLoger && len(t.sess) > 0 {
|
// if model.EnableLoger && len(t.sess) > 0 {
|
||||||
// for ip, sessions := range t.sess {
|
// for ip, sessions := range t.sess {
|
||||||
// Logger.Info(fmt.Sprintf("会话信息: IP=%v, 会话数=%d",
|
// Logger.Info(fmt.Sprintf("会话信息: IP=%v, 会话数=%d",
|
||||||
// net.IP([]byte(ip)), len(sessions)))
|
// net.IP([]byte(ip)), len(sessions)))
|
||||||
@ -325,11 +326,11 @@ func (t *Tracer) serveReply(dst net.IP, res *packet) error {
|
|||||||
// }
|
// }
|
||||||
// 查找对应的会话
|
// 查找对应的会话
|
||||||
a := t.sess[string(shortDst)]
|
a := t.sess[string(shortDst)]
|
||||||
if len(a) == 0 && EnableLoger {
|
if len(a) == 0 && model.EnableLoger {
|
||||||
Logger.Warn(fmt.Sprintf("找不到目标IP=%v的会话", dst))
|
Logger.Warn(fmt.Sprintf("找不到目标IP=%v的会话", dst))
|
||||||
}
|
}
|
||||||
for _, s := range a {
|
for _, s := range a {
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(fmt.Sprintf("处理会话响应: 会话目标=%v", s.ip))
|
Logger.Info(fmt.Sprintf("处理会话响应: 会话目标=%v", s.ip))
|
||||||
}
|
}
|
||||||
s.handle(res)
|
s.handle(res)
|
||||||
@ -395,13 +396,13 @@ func (s *Session) handle(res *packet) {
|
|||||||
now := res.Time
|
now := res.Time
|
||||||
n := 0
|
n := 0
|
||||||
var req *packet
|
var req *packet
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(fmt.Sprintf("处理会话响应: 会话目标=%v, 响应源=%v, ID=%d, TTL=%d",
|
Logger.Info(fmt.Sprintf("处理会话响应: 会话目标=%v, 响应源=%v, ID=%d, TTL=%d",
|
||||||
s.ip, res.IP, res.ID, res.TTL))
|
s.ip, res.IP, res.ID, res.TTL))
|
||||||
}
|
}
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
// // 打印出所有待处理的探测包
|
// // 打印出所有待处理的探测包
|
||||||
// if EnableLoger && len(s.probes) > 0 {
|
// if model.EnableLoger && len(s.probes) > 0 {
|
||||||
// Logger.Info(fmt.Sprintf("当前会话有 %d 个待处理的探测包", len(s.probes)))
|
// Logger.Info(fmt.Sprintf("当前会话有 %d 个待处理的探测包", len(s.probes)))
|
||||||
// for i, probe := range s.probes {
|
// for i, probe := range s.probes {
|
||||||
// Logger.Info(fmt.Sprintf("探测包 #%d: ID=%d, TTL=%d, 时间=%v",
|
// Logger.Info(fmt.Sprintf("探测包 #%d: ID=%d, TTL=%d, 时间=%v",
|
||||||
@ -411,14 +412,14 @@ func (s *Session) handle(res *packet) {
|
|||||||
// 查找匹配的请求包
|
// 查找匹配的请求包
|
||||||
for _, r := range s.probes {
|
for _, r := range s.probes {
|
||||||
if now.Sub(r.Time) > s.t.Timeout {
|
if now.Sub(r.Time) > s.t.Timeout {
|
||||||
// if EnableLoger {
|
// if model.EnableLoger {
|
||||||
// Logger.Info(fmt.Sprintf("探测包超时: ID=%d, TTL=%d", r.ID, r.TTL))
|
// Logger.Info(fmt.Sprintf("探测包超时: ID=%d, TTL=%d", r.ID, r.TTL))
|
||||||
// }
|
// }
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// 对于IPv6 松散匹配
|
// 对于IPv6 松散匹配
|
||||||
if r.ID == res.ID || res.IP.To4() == nil {
|
if r.ID == res.ID || res.IP.To4() == nil {
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(fmt.Sprintf("找到匹配的探测包: ID=%d, TTL=%d", r.ID, r.TTL))
|
Logger.Info(fmt.Sprintf("找到匹配的探测包: ID=%d, TTL=%d", r.ID, r.TTL))
|
||||||
}
|
}
|
||||||
req = r
|
req = r
|
||||||
@ -430,7 +431,7 @@ func (s *Session) handle(res *packet) {
|
|||||||
s.probes = s.probes[:n]
|
s.probes = s.probes[:n]
|
||||||
s.mu.Unlock()
|
s.mu.Unlock()
|
||||||
if req == nil {
|
if req == nil {
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Warn(fmt.Sprintf("未找到匹配的探测包: 响应ID=%d", res.ID))
|
Logger.Warn(fmt.Sprintf("未找到匹配的探测包: 响应ID=%d", res.ID))
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -439,7 +440,7 @@ func (s *Session) handle(res *packet) {
|
|||||||
if hops < 1 {
|
if hops < 1 {
|
||||||
hops = 1
|
hops = 1
|
||||||
}
|
}
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(fmt.Sprintf("创建响应: IP=%v, RTT=%v, Hops=%d",
|
Logger.Info(fmt.Sprintf("创建响应: IP=%v, RTT=%v, Hops=%d",
|
||||||
res.IP, res.Time.Sub(req.Time), hops))
|
res.IP, res.Time.Sub(req.Time), hops))
|
||||||
}
|
}
|
||||||
@ -449,11 +450,11 @@ func (s *Session) handle(res *packet) {
|
|||||||
RTT: res.Time.Sub(req.Time),
|
RTT: res.Time.Sub(req.Time),
|
||||||
Hops: hops,
|
Hops: hops,
|
||||||
}:
|
}:
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info("响应已发送到通道")
|
Logger.Info("响应已发送到通道")
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Warn("发送响应到通道失败,通道已满")
|
Logger.Warn("发送响应到通道失败,通道已满")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/oneclickvirt/backtrace/model"
|
||||||
. "github.com/oneclickvirt/defaultset"
|
. "github.com/oneclickvirt/defaultset"
|
||||||
"golang.org/x/net/icmp"
|
"golang.org/x/net/icmp"
|
||||||
"golang.org/x/net/ipv4"
|
"golang.org/x/net/ipv4"
|
||||||
@ -39,37 +40,37 @@ func newPacketV4(id uint16, dst net.IP, ttl int) []byte {
|
|||||||
|
|
||||||
// trace IPv4追踪函数
|
// trace IPv4追踪函数
|
||||||
func trace(ch chan Result, i int) {
|
func trace(ch chan Result, i int) {
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
InitLogger()
|
InitLogger()
|
||||||
defer Logger.Sync()
|
defer Logger.Sync()
|
||||||
Logger.Info(fmt.Sprintf("开始追踪 %s (%s)", ipv4Names[i], ipv4s[i]))
|
Logger.Info(fmt.Sprintf("开始追踪 %s (%s)", model.Ipv4Names[i], model.Ipv4s[i]))
|
||||||
}
|
}
|
||||||
hops, err := Trace(net.ParseIP(ipv4s[i]))
|
hops, err := Trace(net.ParseIP(model.Ipv4s[i]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s := fmt.Sprintf("%v %-15s %v", ipv4Names[i], ipv4s[i], err)
|
s := fmt.Sprintf("%v %-15s %v", model.Ipv4Names[i], model.Ipv4s[i], err)
|
||||||
|
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Error(fmt.Sprintf("追踪 %s (%s) 失败: %v", ipv4Names[i], ipv4s[i], err))
|
Logger.Error(fmt.Sprintf("追踪 %s (%s) 失败: %v", model.Ipv4Names[i], model.Ipv4s[i], err))
|
||||||
}
|
}
|
||||||
ch <- Result{i, s}
|
ch <- Result{i, s}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 记录每个hop的信息
|
// 记录每个hop的信息
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
for hopNum, hop := range hops {
|
for hopNum, hop := range hops {
|
||||||
for nodeNum, node := range hop.Nodes {
|
for nodeNum, node := range hop.Nodes {
|
||||||
Logger.Info(fmt.Sprintf("追踪 %s (%s) - Hop %d, Node %d: %s (RTT: %v)",
|
Logger.Info(fmt.Sprintf("追踪 %s (%s) - Hop %d, Node %d: %s (RTT: %v)",
|
||||||
ipv4Names[i], ipv4s[i], hopNum+1, nodeNum+1, node.IP.String(), node.RTT))
|
model.Ipv4Names[i], model.Ipv4s[i], hopNum+1, nodeNum+1, node.IP.String(), node.RTT))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var asns []string
|
var asns []string
|
||||||
for _, h := range hops {
|
for _, h := range hops {
|
||||||
for _, n := range h.Nodes {
|
for _, n := range h.Nodes {
|
||||||
asn := ipAsn(n.IP.String())
|
asn := ipv4Asn(n.IP.String())
|
||||||
if asn != "" {
|
if asn != "" {
|
||||||
asns = append(asns, asn)
|
asns = append(asns, asn)
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(fmt.Sprintf("IP %s 对应的ASN: %s", n.IP.String(), asn))
|
Logger.Info(fmt.Sprintf("IP %s 对应的ASN: %s", n.IP.String(), asn))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,7 +80,7 @@ func trace(ch chan Result, i int) {
|
|||||||
if asns != nil && len(asns) > 0 {
|
if asns != nil && len(asns) > 0 {
|
||||||
var tempText string
|
var tempText string
|
||||||
asns = removeDuplicates(asns)
|
asns = removeDuplicates(asns)
|
||||||
tempText += fmt.Sprintf("%v ", ipv4Names[i])
|
tempText += fmt.Sprintf("%v ", model.Ipv4Names[i])
|
||||||
hasAS4134 := false
|
hasAS4134 := false
|
||||||
hasAS4809 := false
|
hasAS4809 := false
|
||||||
for _, asn := range asns {
|
for _, asn := range asns {
|
||||||
@ -94,19 +95,19 @@ func trace(ch chan Result, i int) {
|
|||||||
if hasAS4134 && hasAS4809 {
|
if hasAS4134 && hasAS4809 {
|
||||||
// 同时包含 AS4134 和 AS4809 属于 CN2GT
|
// 同时包含 AS4134 和 AS4809 属于 CN2GT
|
||||||
asns = append([]string{"AS4809b"}, asns...)
|
asns = append([]string{"AS4809b"}, asns...)
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(fmt.Sprintf("%s (%s) 线路识别为: CN2GT", ipv4Names[i], ipv4s[i]))
|
Logger.Info(fmt.Sprintf("%s (%s) 线路识别为: CN2GT", model.Ipv4Names[i], model.Ipv4s[i]))
|
||||||
}
|
}
|
||||||
} else if hasAS4809 {
|
} else if hasAS4809 {
|
||||||
// 仅包含 AS4809 属于 CN2GIA
|
// 仅包含 AS4809 属于 CN2GIA
|
||||||
asns = append([]string{"AS4809a"}, asns...)
|
asns = append([]string{"AS4809a"}, asns...)
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(fmt.Sprintf("%s (%s) 线路识别为: CN2GIA", ipv4Names[i], ipv4s[i]))
|
Logger.Info(fmt.Sprintf("%s (%s) 线路识别为: CN2GIA", model.Ipv4Names[i], model.Ipv4s[i]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tempText += fmt.Sprintf("%-24s ", ipv4s[i])
|
tempText += fmt.Sprintf("%-24s ", model.Ipv4s[i])
|
||||||
for _, asn := range asns {
|
for _, asn := range asns {
|
||||||
asnDescription := m[asn]
|
asnDescription := model.M[asn]
|
||||||
switch asn {
|
switch asn {
|
||||||
case "":
|
case "":
|
||||||
continue
|
continue
|
||||||
@ -138,22 +139,22 @@ func trace(ch chan Result, i int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if tempText == (fmt.Sprintf("%v ", ipv4Names[i]) + fmt.Sprintf("%-15s ", ipv4s[i])) {
|
if tempText == (fmt.Sprintf("%v ", model.Ipv4Names[i]) + fmt.Sprintf("%-15s ", model.Ipv4s[i])) {
|
||||||
tempText += fmt.Sprintf("%v", Red("检测不到已知线路的ASN"))
|
tempText += fmt.Sprintf("%v", Red("检测不到已知线路的ASN"))
|
||||||
|
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Warn(fmt.Sprintf("%s (%s) 检测不到已知线路的ASN", ipv4Names[i], ipv4s[i]))
|
Logger.Warn(fmt.Sprintf("%s (%s) 检测不到已知线路的ASN", model.Ipv4Names[i], model.Ipv4s[i]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(fmt.Sprintf("%s (%s) 追踪完成,结果: %s", ipv4Names[i], ipv4s[i], tempText))
|
Logger.Info(fmt.Sprintf("%s (%s) 追踪完成,结果: %s", model.Ipv4Names[i], model.Ipv4s[i], tempText))
|
||||||
}
|
}
|
||||||
ch <- Result{i, tempText}
|
ch <- Result{i, tempText}
|
||||||
} else {
|
} else {
|
||||||
s := fmt.Sprintf("%v %-15s %v", ipv4Names[i], ipv4s[i], Red("检测不到回程路由节点的IP地址"))
|
s := fmt.Sprintf("%v %-15s %v", model.Ipv4Names[i], model.Ipv4s[i], Red("检测不到回程路由节点的IP地址"))
|
||||||
|
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Warn(fmt.Sprintf("%s (%s) 检测不到回程路由节点的IP地址", ipv4Names[i], ipv4s[i]))
|
Logger.Warn(fmt.Sprintf("%s (%s) 检测不到回程路由节点的IP地址", model.Ipv4Names[i], model.Ipv4s[i]))
|
||||||
}
|
}
|
||||||
ch <- Result{i, s}
|
ch <- Result{i, s}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/oneclickvirt/backtrace/model"
|
||||||
. "github.com/oneclickvirt/defaultset"
|
. "github.com/oneclickvirt/defaultset"
|
||||||
"golang.org/x/net/icmp"
|
"golang.org/x/net/icmp"
|
||||||
"golang.org/x/net/ipv6"
|
"golang.org/x/net/ipv6"
|
||||||
@ -27,7 +28,7 @@ func newPacketV6(id uint16, dst net.IP, ttl int) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Tracer) serveIPv6(conn *ipv6.PacketConn) error {
|
func (t *Tracer) serveIPv6(conn *ipv6.PacketConn) error {
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
InitLogger()
|
InitLogger()
|
||||||
defer Logger.Sync()
|
defer Logger.Sync()
|
||||||
}
|
}
|
||||||
@ -36,17 +37,17 @@ func (t *Tracer) serveIPv6(conn *ipv6.PacketConn) error {
|
|||||||
for {
|
for {
|
||||||
n, cm, src, err := conn.ReadFrom(buf)
|
n, cm, src, err := conn.ReadFrom(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Error("读取IPv6响应失败: " + err.Error())
|
Logger.Error("读取IPv6响应失败: " + err.Error())
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(fmt.Sprintf("收到IPv6响应: 来源=%v, 跳数=%d", src, cm.HopLimit))
|
Logger.Info(fmt.Sprintf("收到IPv6响应: 来源=%v, 跳数=%d", src, cm.HopLimit))
|
||||||
}
|
}
|
||||||
fromIP := src.(*net.IPAddr).IP
|
fromIP := src.(*net.IPAddr).IP
|
||||||
err = t.serveData(fromIP, buf[:n])
|
err = t.serveData(fromIP, buf[:n])
|
||||||
if err != nil && EnableLoger {
|
if err != nil && model.EnableLoger {
|
||||||
Logger.Warn("处理IPv6数据失败: " + err.Error())
|
Logger.Warn("处理IPv6数据失败: " + err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -54,36 +55,36 @@ func (t *Tracer) serveIPv6(conn *ipv6.PacketConn) error {
|
|||||||
|
|
||||||
// traceIPv6 IPv6追踪函数
|
// traceIPv6 IPv6追踪函数
|
||||||
func traceIPv6(ch chan Result, i int, offset int) {
|
func traceIPv6(ch chan Result, i int, offset int) {
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
InitLogger()
|
InitLogger()
|
||||||
defer Logger.Sync()
|
defer Logger.Sync()
|
||||||
Logger.Info(fmt.Sprintf("开始追踪 %s (%s)", ipv6Names[i], ipv6s[i]))
|
Logger.Info(fmt.Sprintf("开始追踪 %s (%s)", model.Ipv6Names[i], model.Ipv6s[i]))
|
||||||
}
|
}
|
||||||
hops, err := Trace(net.ParseIP(ipv6s[i]))
|
hops, err := Trace(net.ParseIP(model.Ipv6s[i]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s := fmt.Sprintf("%v %-24s %v", ipv6Names[i], ipv6s[i], err)
|
s := fmt.Sprintf("%v %-24s %v", model.Ipv6Names[i], model.Ipv6s[i], err)
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Error(fmt.Sprintf("追踪 %s (%s) 失败: %v", ipv6Names[i], ipv6s[i], err))
|
Logger.Error(fmt.Sprintf("追踪 %s (%s) 失败: %v", model.Ipv6Names[i], model.Ipv6s[i], err))
|
||||||
}
|
}
|
||||||
ch <- Result{i + offset, s}
|
ch <- Result{i + offset, s}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 记录每个hop的信息
|
// 记录每个hop的信息
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
for hopNum, hop := range hops {
|
for hopNum, hop := range hops {
|
||||||
for nodeNum, node := range hop.Nodes {
|
for nodeNum, node := range hop.Nodes {
|
||||||
Logger.Info(fmt.Sprintf("追踪 %s (%s) - Hop %d, Node %d: %s (RTT: %v)",
|
Logger.Info(fmt.Sprintf("追踪 %s (%s) - Hop %d, Node %d: %s (RTT: %v)",
|
||||||
ipv6Names[i], ipv6s[i], hopNum+1, nodeNum+1, node.IP.String(), node.RTT))
|
model.Ipv6Names[i], model.Ipv6s[i], hopNum+1, nodeNum+1, node.IP.String(), node.RTT))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var asns []string
|
var asns []string
|
||||||
for _, h := range hops {
|
for _, h := range hops {
|
||||||
for _, n := range h.Nodes {
|
for _, n := range h.Nodes {
|
||||||
asn := ipAsn(n.IP.String())
|
asn := ipv6Asn(n.IP.String())
|
||||||
if asn != "" {
|
if asn != "" {
|
||||||
asns = append(asns, asn)
|
asns = append(asns, asn)
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(fmt.Sprintf("IP %s 对应的ASN: %s", n.IP.String(), asn))
|
Logger.Info(fmt.Sprintf("IP %s 对应的ASN: %s", n.IP.String(), asn))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -93,7 +94,7 @@ func traceIPv6(ch chan Result, i int, offset int) {
|
|||||||
if asns != nil && len(asns) > 0 {
|
if asns != nil && len(asns) > 0 {
|
||||||
var tempText string
|
var tempText string
|
||||||
asns = removeDuplicates(asns)
|
asns = removeDuplicates(asns)
|
||||||
tempText += fmt.Sprintf("%v ", ipv6Names[i])
|
tempText += fmt.Sprintf("%v ", model.Ipv6Names[i])
|
||||||
hasAS4134 := false
|
hasAS4134 := false
|
||||||
hasAS4809 := false
|
hasAS4809 := false
|
||||||
for _, asn := range asns {
|
for _, asn := range asns {
|
||||||
@ -108,19 +109,19 @@ func traceIPv6(ch chan Result, i int, offset int) {
|
|||||||
if hasAS4134 && hasAS4809 {
|
if hasAS4134 && hasAS4809 {
|
||||||
// 同时包含 AS4134 和 AS4809 属于 CN2GT
|
// 同时包含 AS4134 和 AS4809 属于 CN2GT
|
||||||
asns = append([]string{"AS4809b"}, asns...)
|
asns = append([]string{"AS4809b"}, asns...)
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(fmt.Sprintf("%s (%s) 线路识别为: CN2GT", ipv6Names[i], ipv6s[i]))
|
Logger.Info(fmt.Sprintf("%s (%s) 线路识别为: CN2GT", model.Ipv6Names[i], model.Ipv6s[i]))
|
||||||
}
|
}
|
||||||
} else if hasAS4809 {
|
} else if hasAS4809 {
|
||||||
// 仅包含 AS4809 属于 CN2GIA
|
// 仅包含 AS4809 属于 CN2GIA
|
||||||
asns = append([]string{"AS4809a"}, asns...)
|
asns = append([]string{"AS4809a"}, asns...)
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(fmt.Sprintf("%s (%s) 线路识别为: CN2GIA", ipv6Names[i], ipv6s[i]))
|
Logger.Info(fmt.Sprintf("%s (%s) 线路识别为: CN2GIA", model.Ipv6Names[i], model.Ipv6s[i]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tempText += fmt.Sprintf("%-24s ", ipv6s[i])
|
tempText += fmt.Sprintf("%-24s ", model.Ipv6s[i])
|
||||||
for _, asn := range asns {
|
for _, asn := range asns {
|
||||||
asnDescription := m[asn]
|
asnDescription := model.M[asn]
|
||||||
switch asn {
|
switch asn {
|
||||||
case "":
|
case "":
|
||||||
continue
|
continue
|
||||||
@ -152,21 +153,21 @@ func traceIPv6(ch chan Result, i int, offset int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if tempText == (fmt.Sprintf("%v ", ipv6Names[i]) + fmt.Sprintf("%-40s ", ipv6s[i])) {
|
if tempText == (fmt.Sprintf("%v ", model.Ipv6Names[i]) + fmt.Sprintf("%-40s ", model.Ipv6s[i])) {
|
||||||
tempText += fmt.Sprintf("%v", Red("检测不到已知线路的ASN"))
|
tempText += fmt.Sprintf("%v", Red("检测不到已知线路的ASN"))
|
||||||
|
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Warn(fmt.Sprintf("%s (%s) 检测不到已知线路的ASN", ipv6Names[i], ipv6s[i]))
|
Logger.Warn(fmt.Sprintf("%s (%s) 检测不到已知线路的ASN", model.Ipv6Names[i], model.Ipv6s[i]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Info(fmt.Sprintf("%s (%s) 追踪完成,结果: %s", ipv6Names[i], ipv6s[i], tempText))
|
Logger.Info(fmt.Sprintf("%s (%s) 追踪完成,结果: %s", model.Ipv6Names[i], model.Ipv6s[i], tempText))
|
||||||
}
|
}
|
||||||
ch <- Result{i + offset, tempText}
|
ch <- Result{i + offset, tempText}
|
||||||
} else {
|
} else {
|
||||||
s := fmt.Sprintf("%v %-24s %v", ipv6Names[i], ipv6s[i], Red("检测不到回程路由节点的IP地址"))
|
s := fmt.Sprintf("%v %-24s %v", model.Ipv6Names[i], model.Ipv6s[i], Red("检测不到回程路由节点的IP地址"))
|
||||||
if EnableLoger {
|
if model.EnableLoger {
|
||||||
Logger.Warn(fmt.Sprintf("%s (%s) 检测不到回程路由节点的IP地址", ipv6Names[i], ipv6s[i]))
|
Logger.Warn(fmt.Sprintf("%s (%s) 检测不到回程路由节点的IP地址", model.Ipv6Names[i], model.Ipv6s[i]))
|
||||||
}
|
}
|
||||||
ch <- Result{i + offset, s}
|
ch <- Result{i + offset, s}
|
||||||
}
|
}
|
||||||
|
66
bk/utils.go
Normal file
66
bk/utils.go
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
package backtrace
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/imroc/req/v3"
|
||||||
|
"github.com/oneclickvirt/backtrace/model"
|
||||||
|
|
||||||
|
. "github.com/oneclickvirt/defaultset"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Result struct {
|
||||||
|
i int
|
||||||
|
s string
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeDuplicates(elements []string) []string {
|
||||||
|
encountered := map[string]bool{} // 用于存储已经遇到的元素
|
||||||
|
result := []string{} // 存储去重后的结果
|
||||||
|
for v := range elements { // 遍历切片中的元素
|
||||||
|
if encountered[elements[v]] == true { // 如果该元素已经遇到过
|
||||||
|
// 存在过就不加入了
|
||||||
|
} else {
|
||||||
|
encountered[elements[v]] = true // 将该元素标记为已经遇到
|
||||||
|
result = append(result, elements[v]) // 将该元素加入到结果切片中
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result // 返回去重后的结果切片
|
||||||
|
}
|
||||||
|
|
||||||
|
func getData(endpoint string) string {
|
||||||
|
client := req.C()
|
||||||
|
client.SetTimeout(10 * time.Second)
|
||||||
|
client.R().
|
||||||
|
SetRetryCount(2).
|
||||||
|
SetRetryBackoffInterval(1*time.Second, 5*time.Second).
|
||||||
|
SetRetryFixedInterval(2 * time.Second)
|
||||||
|
if model.EnableLoger {
|
||||||
|
InitLogger()
|
||||||
|
defer Logger.Sync()
|
||||||
|
}
|
||||||
|
for _, baseUrl := range model.CdnList {
|
||||||
|
url := baseUrl + endpoint
|
||||||
|
resp, err := client.R().Get(url)
|
||||||
|
if err == nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
b, err := io.ReadAll(resp.Body)
|
||||||
|
if strings.Contains(string(b), "error") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
if model.EnableLoger {
|
||||||
|
Logger.Info(fmt.Sprintf("Received data length: %d", len(b)))
|
||||||
|
}
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if model.EnableLoger {
|
||||||
|
Logger.Info(fmt.Sprintf("HTTP request failed: %v", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
@ -1,5 +0,0 @@
|
|||||||
package backtrace
|
|
||||||
|
|
||||||
const BackTraceVersion = "v0.0.5"
|
|
||||||
|
|
||||||
var EnableLoger = false
|
|
@ -5,10 +5,11 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"runtime"
|
|
||||||
"os"
|
"os"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
backtrace "github.com/oneclickvirt/backtrace/bk"
|
backtrace "github.com/oneclickvirt/backtrace/bk"
|
||||||
|
"github.com/oneclickvirt/backtrace/model"
|
||||||
. "github.com/oneclickvirt/defaultset"
|
. "github.com/oneclickvirt/defaultset"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -30,7 +31,7 @@ func main() {
|
|||||||
backtraceFlag.BoolVar(&help, "h", false, "Show help information")
|
backtraceFlag.BoolVar(&help, "h", false, "Show help information")
|
||||||
backtraceFlag.BoolVar(&showVersion, "v", false, "Show version")
|
backtraceFlag.BoolVar(&showVersion, "v", false, "Show version")
|
||||||
backtraceFlag.BoolVar(&showIpInfo, "s", true, "Disabe show ip info")
|
backtraceFlag.BoolVar(&showIpInfo, "s", true, "Disabe show ip info")
|
||||||
backtraceFlag.BoolVar(&backtrace.EnableLoger, "log", false, "Enable logging")
|
backtraceFlag.BoolVar(&model.EnableLoger, "log", false, "Enable logging")
|
||||||
backtraceFlag.BoolVar(&test, "test", false, "Test Mode")
|
backtraceFlag.BoolVar(&test, "test", false, "Test Mode")
|
||||||
backtraceFlag.Parse(os.Args[1:])
|
backtraceFlag.Parse(os.Args[1:])
|
||||||
if help {
|
if help {
|
||||||
@ -39,7 +40,7 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if showVersion {
|
if showVersion {
|
||||||
fmt.Println(backtrace.BackTraceVersion)
|
fmt.Println(model.BackTraceVersion)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if showIpInfo {
|
if showIpInfo {
|
||||||
|
23
go.mod
23
go.mod
@ -4,11 +4,30 @@ go 1.22.4
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/oneclickvirt/defaultset v0.0.0-20240624051018-30a50859e1b5
|
github.com/oneclickvirt/defaultset v0.0.0-20240624051018-30a50859e1b5
|
||||||
golang.org/x/net v0.26.0
|
golang.org/x/net v0.33.0
|
||||||
golang.org/x/sys v0.21.0
|
golang.org/x/sys v0.28.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/andybalholm/brotli v1.1.1 // indirect
|
||||||
|
github.com/cloudflare/circl v1.5.0 // indirect
|
||||||
|
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
|
||||||
|
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect
|
||||||
|
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||||
|
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||||
|
github.com/imroc/req/v3 v3.50.0 // indirect
|
||||||
|
github.com/klauspost/compress v1.17.11 // indirect
|
||||||
|
github.com/onsi/ginkgo/v2 v2.22.0 // indirect
|
||||||
|
github.com/quic-go/qpack v0.5.1 // indirect
|
||||||
|
github.com/quic-go/quic-go v0.48.2 // indirect
|
||||||
|
github.com/refraction-networking/utls v1.6.7 // indirect
|
||||||
|
go.uber.org/mock v0.5.0 // indirect
|
||||||
go.uber.org/multierr v1.10.0 // indirect
|
go.uber.org/multierr v1.10.0 // indirect
|
||||||
go.uber.org/zap v1.27.0 // indirect
|
go.uber.org/zap v1.27.0 // indirect
|
||||||
|
golang.org/x/crypto v0.31.0 // indirect
|
||||||
|
golang.org/x/exp v0.0.0-20241215155358-4a5509556b9e // indirect
|
||||||
|
golang.org/x/mod v0.22.0 // indirect
|
||||||
|
golang.org/x/sync v0.10.0 // indirect
|
||||||
|
golang.org/x/text v0.21.0 // indirect
|
||||||
|
golang.org/x/tools v0.28.0 // indirect
|
||||||
)
|
)
|
||||||
|
44
go.sum
44
go.sum
@ -1,20 +1,64 @@
|
|||||||
|
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
|
||||||
|
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
|
||||||
|
github.com/cloudflare/circl v1.5.0 h1:hxIWksrX6XN5a1L2TI/h53AGPhNHoUBo+TD1ms9+pys=
|
||||||
|
github.com/cloudflare/circl v1.5.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||||
|
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||||
|
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg=
|
||||||
|
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||||
|
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
|
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||||
|
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
|
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||||
|
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||||
|
github.com/imroc/req/v3 v3.50.0 h1:n3BVnZiTRpvkN5T1IB79LC/THhFU9iXksNRMH4ZNVaY=
|
||||||
|
github.com/imroc/req/v3 v3.50.0/go.mod h1:tsOk8K7zI6cU4xu/VWCZVtq9Djw9IWm4MslKzme5woU=
|
||||||
|
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
|
||||||
|
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||||
github.com/oneclickvirt/defaultset v0.0.0-20240624051018-30a50859e1b5 h1:TUM6XzOB7Z7OxyXi3fwlZY9KfuVbvUBusYiNbSfX208=
|
github.com/oneclickvirt/defaultset v0.0.0-20240624051018-30a50859e1b5 h1:TUM6XzOB7Z7OxyXi3fwlZY9KfuVbvUBusYiNbSfX208=
|
||||||
github.com/oneclickvirt/defaultset v0.0.0-20240624051018-30a50859e1b5/go.mod h1:e9Jt4tf2sbemCtc84/XgKcHy9EZ2jkc5x2sW1NiJS+E=
|
github.com/oneclickvirt/defaultset v0.0.0-20240624051018-30a50859e1b5/go.mod h1:e9Jt4tf2sbemCtc84/XgKcHy9EZ2jkc5x2sW1NiJS+E=
|
||||||
|
github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg=
|
||||||
|
github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
|
||||||
|
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
|
||||||
|
github.com/quic-go/quic-go v0.48.2 h1:wsKXZPeGWpMpCGSWqOcqpW2wZYic/8T3aqiOID0/KWE=
|
||||||
|
github.com/quic-go/quic-go v0.48.2/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs=
|
||||||
|
github.com/refraction-networking/utls v1.6.7 h1:zVJ7sP1dJx/WtVuITug3qYUq034cDq9B2MR1K67ULZM=
|
||||||
|
github.com/refraction-networking/utls v1.6.7/go.mod h1:BC3O4vQzye5hqpmDTWUqi4P5DDhzJfkV1tdqtawQIH0=
|
||||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
||||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||||
|
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
|
||||||
|
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
|
||||||
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
|
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
|
||||||
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||||
|
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
||||||
|
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||||
|
golang.org/x/exp v0.0.0-20241215155358-4a5509556b9e h1:4qufH0hlUYs6AO6XmZC3GqfDPGSXHVXUFR6OND+iJX4=
|
||||||
|
golang.org/x/exp v0.0.0-20241215155358-4a5509556b9e/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c=
|
||||||
|
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
|
||||||
|
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||||
|
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
|
||||||
|
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||||
|
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
||||||
|
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||||
|
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||||
|
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||||
|
golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8=
|
||||||
|
golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
65
model/model.go
Normal file
65
model/model.go
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
const BackTraceVersion = "v0.0.5"
|
||||||
|
|
||||||
|
var EnableLoger = false
|
||||||
|
|
||||||
|
var (
|
||||||
|
IcmpTargets = "https://raw.githubusercontent.com/spiritLHLS/icmp_targets/refs/heads/main/nodes.json"
|
||||||
|
CdnList = []string{
|
||||||
|
"http://cdn1.spiritlhl.net/",
|
||||||
|
"http://cdn2.spiritlhl.net/",
|
||||||
|
"http://cdn3.spiritlhl.net/",
|
||||||
|
"http://cdn4.spiritlhl.net/",
|
||||||
|
}
|
||||||
|
Ipv4s = []string{
|
||||||
|
"219.141.140.10", // 北京电信v4
|
||||||
|
"202.106.195.68", // 北京联通v4
|
||||||
|
"221.179.155.161", // 北京移动v4
|
||||||
|
"202.96.209.133", // 上海电信v4
|
||||||
|
"210.22.97.1", // 上海联通v4
|
||||||
|
"211.136.112.200", // 上海移动v4
|
||||||
|
"58.60.188.222", // 广州电信v4
|
||||||
|
"210.21.196.6", // 广州联通v4
|
||||||
|
"120.196.165.24", // 广州移动v4
|
||||||
|
"61.139.2.69", // 成都电信v4
|
||||||
|
"119.6.6.6", // 成都联通v4
|
||||||
|
"211.137.96.205", // 成都移动v4
|
||||||
|
}
|
||||||
|
|
||||||
|
Ipv4Names = []string{
|
||||||
|
"北京电信v4", "北京联通v4", "北京移动v4",
|
||||||
|
"上海电信v4", "上海联通v4", "上海移动v4",
|
||||||
|
"广州电信v4", "广州联通v4", "广州移动v4",
|
||||||
|
"成都电信v4", "成都联通v4", "成都移动v4",
|
||||||
|
}
|
||||||
|
Ipv6s = []string{
|
||||||
|
"2400:89c0:1053:3::69", // 北京电信 IPv6
|
||||||
|
"2400:89c0:1013:3::54", // 北京联通 IPv6
|
||||||
|
"2409:8c00:8421:1303::55", // 北京移动 IPv6
|
||||||
|
"240e:e1:aa00:4000::24", // 上海电信 IPV6
|
||||||
|
"2408:80f1:21:5003::a", // 上海联通 IPv6
|
||||||
|
"2409:8c1e:75b0:3003::26", // 上海移动 IPv6
|
||||||
|
"240e:97c:2f:3000::44", // 广州电信 IPv6
|
||||||
|
"2408:8756:f50:1001::c", // 广州联通 IPv6
|
||||||
|
"2409:8c54:871:1001::12", // 广州移动 IPv6
|
||||||
|
}
|
||||||
|
Ipv6Names = []string{
|
||||||
|
"北京电信v6", "北京联通v6", "北京移动v6",
|
||||||
|
"上海电信v6", "上海联通v6", "上海移动v6",
|
||||||
|
"广州电信v6", "广州联通v6", "广州移动v6",
|
||||||
|
}
|
||||||
|
M = map[string]string{
|
||||||
|
// [] 前的字符串个数,中文占2个字符串
|
||||||
|
"AS23764": "电信CTGNET [精品线路]",
|
||||||
|
"AS4809a": "电信CN2GIA [精品线路]",
|
||||||
|
"AS4809b": "电信CN2GT [优质线路]",
|
||||||
|
"AS4809": "电信CN2 [优质线路]",
|
||||||
|
"AS4134": "电信163 [普通线路]",
|
||||||
|
"AS9929": "联通9929 [优质线路]",
|
||||||
|
"AS4837": "联通4837 [普通线路]",
|
||||||
|
"AS58807": "移动CMIN2 [精品线路]",
|
||||||
|
"AS9808": "移动CMI [普通线路]",
|
||||||
|
"AS58453": "移动CMI [普通线路]",
|
||||||
|
}
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user