diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 7b9bee6..3fd8302 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -36,7 +36,7 @@ jobs: echo "Deleting asset with ID: $asset" curl -X DELETE -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" "https://api.github.com/repos/oneclickvirt/backtrace/releases/assets/$asset" done - sleep 60 + sleep 30 release-binary: name: Release Go Binary diff --git a/bk/asn.go b/bk/asn.go index 34c4504..de95028 100644 --- a/bk/asn.go +++ b/bk/asn.go @@ -1,11 +1,7 @@ package backtrace import ( - "fmt" - "net" "strings" - - . "github.com/oneclickvirt/defaultset" ) type Result struct { @@ -72,128 +68,6 @@ func removeDuplicates(elements []string) []string { return result // 返回去重后的结果切片 } -// trace IPv4追踪函数 -func trace(ch chan Result, i int) { - if EnableLoger { - InitLogger() - defer Logger.Sync() - Logger.Info(fmt.Sprintf("开始追踪 %s (%s)", ipv4Names[i], ipv4s[i])) - } - hops, err := Trace(net.ParseIP(ipv4s[i])) - if err != nil { - s := fmt.Sprintf("%v %-15s %v", ipv4Names[i], ipv4s[i], err) - - if EnableLoger { - Logger.Error(fmt.Sprintf("追踪 %s (%s) 失败: %v", ipv4Names[i], ipv4s[i], err)) - } - ch <- Result{i, s} - return - } - // 记录每个hop的信息 - if EnableLoger { - for hopNum, hop := range hops { - for nodeNum, node := range hop.Nodes { - 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)) - } - } - } - var asns []string - for _, h := range hops { - for _, n := range h.Nodes { - asn := ipAsn(n.IP.String()) - if asn != "" { - asns = append(asns, asn) - if EnableLoger { - Logger.Info(fmt.Sprintf("IP %s 对应的ASN: %s", n.IP.String(), asn)) - } - } - } - } - // 处理CN2不同路线的区别 - if asns != nil && len(asns) > 0 { - var tempText string - asns = removeDuplicates(asns) - tempText += fmt.Sprintf("%v ", ipv4Names[i]) - hasAS4134 := false - hasAS4809 := false - for _, asn := range asns { - if asn == "AS4134" { - hasAS4134 = true - } - if asn == "AS4809" { - hasAS4809 = true - } - } - // 判断是否包含 AS4134 和 AS4809 - if hasAS4134 && hasAS4809 { - // 同时包含 AS4134 和 AS4809 属于 CN2GT - asns = append([]string{"AS4809b"}, asns...) - if EnableLoger { - Logger.Info(fmt.Sprintf("%s (%s) 线路识别为: CN2GT", ipv4Names[i], ipv4s[i])) - } - } else if hasAS4809 { - // 仅包含 AS4809 属于 CN2GIA - asns = append([]string{"AS4809a"}, asns...) - if EnableLoger { - Logger.Info(fmt.Sprintf("%s (%s) 线路识别为: CN2GIA", ipv4Names[i], ipv4s[i])) - } - } - tempText += fmt.Sprintf("%-15s ", ipv4s[i]) - for _, asn := range asns { - asnDescription := m[asn] - switch asn { - case "": - continue - case "AS4809": // 被 AS4809a 和 AS4809b 替代了 - continue - case "AS9929": - if !strings.Contains(tempText, asnDescription) { - tempText += DarkGreen(asnDescription) + " " - } - case "AS4809a": - if !strings.Contains(tempText, asnDescription) { - tempText += DarkGreen(asnDescription) + " " - } - case "AS23764": - if !strings.Contains(tempText, asnDescription) { - tempText += DarkGreen(asnDescription) + " " - } - case "AS4809b": - if !strings.Contains(tempText, asnDescription) { - tempText += Green(asnDescription) + " " - } - case "AS58807": - if !strings.Contains(tempText, asnDescription) { - tempText += Green(asnDescription) + " " - } - default: - if !strings.Contains(tempText, asnDescription) { - tempText += White(asnDescription) + " " - } - } - } - if tempText == (fmt.Sprintf("%v ", ipv4Names[i]) + fmt.Sprintf("%-15s ", ipv4s[i])) { - tempText += fmt.Sprintf("%v", Red("检测不到已知线路的ASN")) - - if EnableLoger { - Logger.Warn(fmt.Sprintf("%s (%s) 检测不到已知线路的ASN", ipv4Names[i], ipv4s[i])) - } - } - if EnableLoger { - Logger.Info(fmt.Sprintf("%s (%s) 追踪完成,结果: %s", ipv4Names[i], ipv4s[i], tempText)) - } - ch <- Result{i, tempText} - } else { - s := fmt.Sprintf("%v %-15s %v", ipv4Names[i], ipv4s[i], Red("检测不到回程路由节点的IP地址")) - - if EnableLoger { - Logger.Warn(fmt.Sprintf("%s (%s) 检测不到回程路由节点的IP地址", ipv4Names[i], ipv4s[i])) - } - ch <- Result{i, s} - } -} - func ipAsn(ip string) string { if strings.Contains(ip, ":") { return ipv6Asn(ip) diff --git a/bk/trace_common.go b/bk/trace_common.go index 90f5091..1847de2 100644 --- a/bk/trace_common.go +++ b/bk/trace_common.go @@ -316,13 +316,13 @@ func (t *Tracer) serveReply(dst net.IP, res *packet) error { shortDst := shortIP(dst) t.mu.RLock() defer t.mu.RUnlock() - // 调试输出会话信息 - if EnableLoger && len(t.sess) > 0 { - for ip, sessions := range t.sess { - Logger.Info(fmt.Sprintf("会话信息: IP=%v, 会话数=%d", - net.IP([]byte(ip)), len(sessions))) - } - } + // // 调试输出会话信息 + // if EnableLoger && len(t.sess) > 0 { + // for ip, sessions := range t.sess { + // Logger.Info(fmt.Sprintf("会话信息: IP=%v, 会话数=%d", + // net.IP([]byte(ip)), len(sessions))) + // } + // } // 查找对应的会话 a := t.sess[string(shortDst)] if len(a) == 0 && EnableLoger { @@ -400,23 +400,23 @@ func (s *Session) handle(res *packet) { s.ip, res.IP, res.ID, res.TTL)) } s.mu.Lock() - // 打印出所有待处理的探测包 - if EnableLoger && len(s.probes) > 0 { - Logger.Info(fmt.Sprintf("当前会话有 %d 个待处理的探测包", len(s.probes))) - for i, probe := range s.probes { - Logger.Info(fmt.Sprintf("探测包 #%d: ID=%d, TTL=%d, 时间=%v", - i, probe.ID, probe.TTL, probe.Time)) - } - } + // // 打印出所有待处理的探测包 + // if EnableLoger && len(s.probes) > 0 { + // Logger.Info(fmt.Sprintf("当前会话有 %d 个待处理的探测包", len(s.probes))) + // for i, probe := range s.probes { + // Logger.Info(fmt.Sprintf("探测包 #%d: ID=%d, TTL=%d, 时间=%v", + // i, probe.ID, probe.TTL, probe.Time)) + // } + // } // 查找匹配的请求包 for _, r := range s.probes { if now.Sub(r.Time) > s.t.Timeout { - if EnableLoger { - Logger.Info(fmt.Sprintf("探测包超时: ID=%d, TTL=%d", r.ID, r.TTL)) - } + // if EnableLoger { + // Logger.Info(fmt.Sprintf("探测包超时: ID=%d, TTL=%d", r.ID, r.TTL)) + // } continue } - // 对于IPv6,可能需要松散匹配 + // 对于IPv6 松散匹配 if r.ID == res.ID || res.IP.To4() == nil { if EnableLoger { Logger.Info(fmt.Sprintf("找到匹配的探测包: ID=%d, TTL=%d", r.ID, r.TTL)) diff --git a/bk/trace_ipv4.go b/bk/trace_ipv4.go index f69f665..8fe11b5 100644 --- a/bk/trace_ipv4.go +++ b/bk/trace_ipv4.go @@ -1,8 +1,11 @@ package backtrace import ( + "fmt" "net" + "strings" + . "github.com/oneclickvirt/defaultset" "golang.org/x/net/icmp" "golang.org/x/net/ipv4" ) @@ -33,3 +36,125 @@ func newPacketV4(id uint16, dst net.IP, ttl int) []byte { } return append(buf, p...) } + +// trace IPv4追踪函数 +func trace(ch chan Result, i int) { + if EnableLoger { + InitLogger() + defer Logger.Sync() + Logger.Info(fmt.Sprintf("开始追踪 %s (%s)", ipv4Names[i], ipv4s[i])) + } + hops, err := Trace(net.ParseIP(ipv4s[i])) + if err != nil { + s := fmt.Sprintf("%v %-15s %v", ipv4Names[i], ipv4s[i], err) + + if EnableLoger { + Logger.Error(fmt.Sprintf("追踪 %s (%s) 失败: %v", ipv4Names[i], ipv4s[i], err)) + } + ch <- Result{i, s} + return + } + // 记录每个hop的信息 + if EnableLoger { + for hopNum, hop := range hops { + for nodeNum, node := range hop.Nodes { + 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)) + } + } + } + var asns []string + for _, h := range hops { + for _, n := range h.Nodes { + asn := ipAsn(n.IP.String()) + if asn != "" { + asns = append(asns, asn) + if EnableLoger { + Logger.Info(fmt.Sprintf("IP %s 对应的ASN: %s", n.IP.String(), asn)) + } + } + } + } + // 处理CN2不同路线的区别 + if asns != nil && len(asns) > 0 { + var tempText string + asns = removeDuplicates(asns) + tempText += fmt.Sprintf("%v ", ipv4Names[i]) + hasAS4134 := false + hasAS4809 := false + for _, asn := range asns { + if asn == "AS4134" { + hasAS4134 = true + } + if asn == "AS4809" { + hasAS4809 = true + } + } + // 判断是否包含 AS4134 和 AS4809 + if hasAS4134 && hasAS4809 { + // 同时包含 AS4134 和 AS4809 属于 CN2GT + asns = append([]string{"AS4809b"}, asns...) + if EnableLoger { + Logger.Info(fmt.Sprintf("%s (%s) 线路识别为: CN2GT", ipv4Names[i], ipv4s[i])) + } + } else if hasAS4809 { + // 仅包含 AS4809 属于 CN2GIA + asns = append([]string{"AS4809a"}, asns...) + if EnableLoger { + Logger.Info(fmt.Sprintf("%s (%s) 线路识别为: CN2GIA", ipv4Names[i], ipv4s[i])) + } + } + tempText += fmt.Sprintf("%-15s ", ipv4s[i]) + for _, asn := range asns { + asnDescription := m[asn] + switch asn { + case "": + continue + case "AS4809": // 被 AS4809a 和 AS4809b 替代了 + continue + case "AS9929": + if !strings.Contains(tempText, asnDescription) { + tempText += DarkGreen(asnDescription) + " " + } + case "AS4809a": + if !strings.Contains(tempText, asnDescription) { + tempText += DarkGreen(asnDescription) + " " + } + case "AS23764": + if !strings.Contains(tempText, asnDescription) { + tempText += DarkGreen(asnDescription) + " " + } + case "AS4809b": + if !strings.Contains(tempText, asnDescription) { + tempText += Green(asnDescription) + " " + } + case "AS58807": + if !strings.Contains(tempText, asnDescription) { + tempText += Green(asnDescription) + " " + } + default: + if !strings.Contains(tempText, asnDescription) { + tempText += White(asnDescription) + " " + } + } + } + if tempText == (fmt.Sprintf("%v ", ipv4Names[i]) + fmt.Sprintf("%-15s ", ipv4s[i])) { + tempText += fmt.Sprintf("%v", Red("检测不到已知线路的ASN")) + + if EnableLoger { + Logger.Warn(fmt.Sprintf("%s (%s) 检测不到已知线路的ASN", ipv4Names[i], ipv4s[i])) + } + } + if EnableLoger { + Logger.Info(fmt.Sprintf("%s (%s) 追踪完成,结果: %s", ipv4Names[i], ipv4s[i], tempText)) + } + ch <- Result{i, tempText} + } else { + s := fmt.Sprintf("%v %-15s %v", ipv4Names[i], ipv4s[i], Red("检测不到回程路由节点的IP地址")) + + if EnableLoger { + Logger.Warn(fmt.Sprintf("%s (%s) 检测不到回程路由节点的IP地址", ipv4Names[i], ipv4s[i])) + } + ch <- Result{i, s} + } +} diff --git a/bk/trace_ipv6.go b/bk/trace_ipv6.go index 2babcbe..fe0f077 100644 --- a/bk/trace_ipv6.go +++ b/bk/trace_ipv6.go @@ -10,33 +10,6 @@ import ( "golang.org/x/net/ipv6" ) -// func newPacketV6(id uint16, dst net.IP, ttl int) []byte { -// // 创建ICMP消息(回显请求) -// msg := icmp.Message{ -// Type: ipv6.ICMPTypeEchoRequest, -// Body: &icmp.Echo{ -// ID: int(id), -// Seq: int(id), -// }, -// } -// // 序列化ICMP消息 -// icmpData, _ := msg.Marshal(nil) -// // 手动创建原始IPv6数据包头部 -// ipHeaderBytes := make([]byte, ipv6.HeaderLen) -// // 设置版本和流量类别(第一个字节) -// ipHeaderBytes[0] = (ipv6.Version << 4) -// // 设置下一个头部(协议) -// ipHeaderBytes[6] = ProtocolIPv6ICMP -// // 设置跳数限制 -// ipHeaderBytes[7] = byte(ttl) -// // 设置有效载荷长度(2字节字段) -// binary.BigEndian.PutUint16(ipHeaderBytes[4:6], uint16(len(icmpData))) -// // 设置目标地址(最后16个字节) -// copy(ipHeaderBytes[24:40], dst.To16()) -// // 合并头部和ICMP数据 -// return append(ipHeaderBytes, icmpData...) -// } - func newPacketV6(id uint16, dst net.IP, ttl int) []byte { // 使用ipv6包的Echo请求 msg := icmp.Message{ @@ -88,7 +61,7 @@ func traceIPv6(ch chan Result, i int, offset int) { } hops, err := Trace(net.ParseIP(ipv6s[i])) if err != nil { - s := fmt.Sprintf("%v %-40s %v", ipv6Names[i], ipv6s[i], err) + s := fmt.Sprintf("%v %-25s %v", ipv6Names[i], ipv6s[i], err) if EnableLoger { Logger.Error(fmt.Sprintf("追踪 %s (%s) 失败: %v", ipv6Names[i], ipv6s[i], err)) }