mirror of
				https://github.com/oneclickvirt/backtrace.git
				synced 2025-11-04 15:52:37 +08:00 
			
		
		
		
	feat: 添加远程备用地址的相关逻辑
This commit is contained in:
		
							parent
							
								
									aad93e51f8
								
							
						
					
					
						commit
						2adf709e63
					
				@ -45,15 +45,29 @@ func trace(ch chan Result, i int) {
 | 
			
		||||
		defer Logger.Sync()
 | 
			
		||||
		Logger.Info(fmt.Sprintf("开始追踪 %s (%s)", model.Ipv4Names[i], model.Ipv4s[i]))
 | 
			
		||||
	}
 | 
			
		||||
	// 先尝试原始IP地址
 | 
			
		||||
	hops, err := Trace(net.ParseIP(model.Ipv4s[i]))
 | 
			
		||||
	if err != nil || len(hops) == 0 {
 | 
			
		||||
		// 如果失败,尝试从IcmpTargets获取备选IP
 | 
			
		||||
		if tryAltIPs := tryAlternativeIPs(model.Ipv4Names[i], "v4"); len(tryAltIPs) > 0 {
 | 
			
		||||
			for _, altIP := range tryAltIPs {
 | 
			
		||||
				if model.EnableLoger {
 | 
			
		||||
					Logger.Info(fmt.Sprintf("尝试备选IP %s 追踪 %s", altIP, model.Ipv4Names[i]))
 | 
			
		||||
				}
 | 
			
		||||
				hops, err = Trace(net.ParseIP(altIP))
 | 
			
		||||
				if err == nil && len(hops) > 0 {
 | 
			
		||||
					break // 成功找到可用IP
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// 如果所有尝试都失败
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		s := fmt.Sprintf("%v %-15s %v", model.Ipv4Names[i], model.Ipv4s[i], err)
 | 
			
		||||
 | 
			
		||||
		s := fmt.Sprintf("%v %-15s %v", model.Ipv4Names[i], model.Ipv4s[i], Red("检测不到回程路由节点的IP地址"))
 | 
			
		||||
		if model.EnableLoger {
 | 
			
		||||
			Logger.Error(fmt.Sprintf("追踪 %s (%s) 失败: %v", model.Ipv4Names[i], model.Ipv4s[i], err))
 | 
			
		||||
		}
 | 
			
		||||
		ch <- Result{i, s}
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	// 记录每个hop的信息
 | 
			
		||||
	if model.EnableLoger {
 | 
			
		||||
@ -151,10 +165,10 @@ func trace(ch chan Result, i int) {
 | 
			
		||||
		}
 | 
			
		||||
		ch <- Result{i, tempText}
 | 
			
		||||
	} else {
 | 
			
		||||
		s := fmt.Sprintf("%v %-15s %v", model.Ipv4Names[i], model.Ipv4s[i], Red("检测不到回程路由节点的IP地址"))
 | 
			
		||||
		s := fmt.Sprintf("%v %-15s %v", model.Ipv4Names[i], model.Ipv4s[i], Red("检测不到回程路由节点的IPV4地址"))
 | 
			
		||||
 | 
			
		||||
		if model.EnableLoger {
 | 
			
		||||
			Logger.Warn(fmt.Sprintf("%s (%s) 检测不到回程路由节点的IP地址", model.Ipv4Names[i], model.Ipv4s[i]))
 | 
			
		||||
			Logger.Warn(fmt.Sprintf("%s (%s) 检测不到回程路由节点的IPV4地址", model.Ipv4Names[i], model.Ipv4s[i]))
 | 
			
		||||
		}
 | 
			
		||||
		ch <- Result{i, s}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -60,14 +60,29 @@ func traceIPv6(ch chan Result, i int, offset int) {
 | 
			
		||||
		defer Logger.Sync()
 | 
			
		||||
		Logger.Info(fmt.Sprintf("开始追踪 %s (%s)", model.Ipv6Names[i], model.Ipv6s[i]))
 | 
			
		||||
	}
 | 
			
		||||
	// 先尝试原始IP地址
 | 
			
		||||
	hops, err := Trace(net.ParseIP(model.Ipv6s[i]))
 | 
			
		||||
	if err != nil || len(hops) == 0 {
 | 
			
		||||
		// 如果失败,尝试从IcmpTargets获取备选IP
 | 
			
		||||
		if tryAltIPs := tryAlternativeIPs(model.Ipv6Names[i], "v6"); len(tryAltIPs) > 0 {
 | 
			
		||||
			for _, altIP := range tryAltIPs {
 | 
			
		||||
				if model.EnableLoger {
 | 
			
		||||
					Logger.Info(fmt.Sprintf("尝试备选IP %s 追踪 %s", altIP, model.Ipv6Names[i]))
 | 
			
		||||
				}
 | 
			
		||||
				hops, err = Trace(net.ParseIP(altIP))
 | 
			
		||||
				if err == nil && len(hops) > 0 {
 | 
			
		||||
					break // 成功找到可用IP
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// 如果所有尝试都失败
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		s := fmt.Sprintf("%v %-24s %v", model.Ipv6Names[i], model.Ipv6s[i], err)
 | 
			
		||||
		s := fmt.Sprintf("%v %-24s %v", model.Ipv6Names[i], model.Ipv6s[i], Red("检测不到回程路由节点的IP地址"))
 | 
			
		||||
		if model.EnableLoger {
 | 
			
		||||
			Logger.Error(fmt.Sprintf("追踪 %s (%s) 失败: %v", model.Ipv6Names[i], model.Ipv6s[i], err))
 | 
			
		||||
			Logger.Warn(fmt.Sprintf("%s (%s) 检测不到回程路由节点的IP地址", model.Ipv6Names[i], model.Ipv6s[i]))
 | 
			
		||||
		}
 | 
			
		||||
		ch <- Result{i + offset, s}
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	// 记录每个hop的信息
 | 
			
		||||
	if model.EnableLoger {
 | 
			
		||||
@ -164,9 +179,9 @@ func traceIPv6(ch chan Result, i int, offset int) {
 | 
			
		||||
		}
 | 
			
		||||
		ch <- Result{i + offset, tempText}
 | 
			
		||||
	} else {
 | 
			
		||||
		s := fmt.Sprintf("%v %-24s %v", model.Ipv6Names[i], model.Ipv6s[i], Red("检测不到回程路由节点的IP地址"))
 | 
			
		||||
		s := fmt.Sprintf("%v %-24s %v", model.Ipv6Names[i], model.Ipv6s[i], Red("检测不到回程路由节点的IPV6地址"))
 | 
			
		||||
		if model.EnableLoger {
 | 
			
		||||
			Logger.Warn(fmt.Sprintf("%s (%s) 检测不到回程路由节点的IP地址", model.Ipv6Names[i], model.Ipv6s[i]))
 | 
			
		||||
			Logger.Warn(fmt.Sprintf("%s (%s) 检测不到回程路由节点的IPV6地址", model.Ipv6Names[i], model.Ipv6s[i]))
 | 
			
		||||
		}
 | 
			
		||||
		ch <- Result{i + offset, s}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										62
									
								
								bk/utils.go
									
									
									
									
									
								
							
							
						
						
									
										62
									
								
								bk/utils.go
									
									
									
									
									
								
							@ -31,6 +31,7 @@ func removeDuplicates(elements []string) []string {
 | 
			
		||||
	return result // 返回去重后的结果切片
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getData 获取目标地址的文本内容
 | 
			
		||||
func getData(endpoint string) string {
 | 
			
		||||
	client := req.C()
 | 
			
		||||
	client.SetTimeout(10 * time.Second)
 | 
			
		||||
@ -64,3 +65,64 @@ func getData(endpoint string) string {
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// tryAlternativeIPs 从IcmpTargets获取备选IP地址
 | 
			
		||||
func tryAlternativeIPs(targetName string, ipVersion string) []string {
 | 
			
		||||
	jsonData := getData(model.IcmpTargets)
 | 
			
		||||
	if jsonData == "" {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	// 简单解析JSON,提取省份和ISP信息
 | 
			
		||||
	var targetProvince, targetISP string
 | 
			
		||||
	// 从目标名称中提取省份和ISP信息
 | 
			
		||||
	if strings.Contains(targetName, "北京") {
 | 
			
		||||
		targetProvince = "北京"
 | 
			
		||||
	} else if strings.Contains(targetName, "上海") {
 | 
			
		||||
		targetProvince = "上海"
 | 
			
		||||
	} else if strings.Contains(targetName, "广州") {
 | 
			
		||||
		targetProvince = "广东"
 | 
			
		||||
	} else if strings.Contains(targetName, "成都") {
 | 
			
		||||
		targetProvince = "四川"
 | 
			
		||||
	}
 | 
			
		||||
	if strings.Contains(targetName, "电信") {
 | 
			
		||||
		targetISP = "电信"
 | 
			
		||||
	} else if strings.Contains(targetName, "联通") {
 | 
			
		||||
		targetISP = "联通"
 | 
			
		||||
	} else if strings.Contains(targetName, "移动") {
 | 
			
		||||
		targetISP = "移动"
 | 
			
		||||
	}
 | 
			
		||||
	// 如果没有提取到信息,返回空
 | 
			
		||||
	if targetProvince == "" || targetISP == "" {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	// 解析JSON数据寻找匹配的记录
 | 
			
		||||
	var result []string
 | 
			
		||||
	for _, line := range strings.Split(jsonData, "},{") {
 | 
			
		||||
		if strings.Contains(line, "\"province\":\""+targetProvince+"省\"") &&
 | 
			
		||||
			strings.Contains(line, "\"isp\":\""+targetISP+"\"") &&
 | 
			
		||||
			strings.Contains(line, "\"ip_version\":\""+ipVersion+"\"") {
 | 
			
		||||
			// 提取IP列表
 | 
			
		||||
			ipsStart := strings.Index(line, "\"ips\":\"") + 7
 | 
			
		||||
			if ipsStart > 7 {
 | 
			
		||||
				ipsEnd := strings.Index(line[ipsStart:], "\"")
 | 
			
		||||
				if ipsEnd > 0 {
 | 
			
		||||
					ipsList := line[ipsStart : ipsStart+ipsEnd]
 | 
			
		||||
					ips := strings.Split(ipsList, ",")
 | 
			
		||||
					// 最多返回3个不重复的IP地址
 | 
			
		||||
					count := 0
 | 
			
		||||
					for _, ip := range ips {
 | 
			
		||||
						if ip != "" {
 | 
			
		||||
							result = append(result, ip)
 | 
			
		||||
							count++
 | 
			
		||||
							if count >= 3 {
 | 
			
		||||
								break
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					return result
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user