fix: preserve type one quality probe owner

This commit is contained in:
sagitchu
2026-05-01 23:32:00 +08:00
parent 55a931510b
commit 869d726b7a
2 changed files with 36 additions and 19 deletions
@@ -229,6 +229,9 @@ func (p *tunnelQualityProber) probeTunnel(tunnelID int64) {
p.storeResult(snap)
return
}
probeTarget := effectiveTunnelProbeTargetValues(tunnel.ProbeTargetHost, tunnel.ProbeTargetPort)
snap.ProbeTargetHost = probeTarget.Host
snap.ProbeTargetPort = probeTarget.Port
chainRows, err := h.listChainNodesForTunnel(tunnelID)
if err != nil || len(chainRows) == 0 {
@@ -245,20 +248,13 @@ func (p *tunnelQualityProber) probeTunnel(tunnelID int64) {
pingTimeoutMS: tunnelQualityPingTimeoutMs,
timeoutMessage: "探测超时",
}
probeTarget := effectiveTunnelProbeTargetValues(tunnel.ProbeTargetHost, tunnel.ProbeTargetPort)
snap.ProbeTargetHost = probeTarget.Host
snap.ProbeTargetPort = probeTarget.Port
p.probeBestExitOwners(tunnelID, inNodes, midNodesGrouped, outNodes, ipPreference, options, probeTarget)
switch tunnel.Type {
case 1:
// Port forwarding: exit/public edge → public probe target when available.
publicProbeNodes := inNodes
if len(outNodes) > 0 {
publicProbeNodes = outNodes
}
if len(publicProbeNodes) > 0 {
lat, loss, err := p.pingNode(publicProbeNodes[0].NodeID, probeTarget.Host, probeTarget.Port, options)
// Port forwarding: entry → public probe target only.
if len(inNodes) > 0 {
lat, loss, err := p.pingNode(inNodes[0].NodeID, probeTarget.Host, probeTarget.Port, options)
if err == nil {
snap.ExitToBingLatency = lat
snap.ExitToBingLoss = loss
@@ -370,13 +366,9 @@ func (p *tunnelQualityProber) probeTunnel(tunnelID int64) {
snap.Success = probeOK
default:
// Unknown type: use exit/public edge when available, otherwise entry.
publicProbeNodes := inNodes
if len(outNodes) > 0 {
publicProbeNodes = outNodes
}
if len(publicProbeNodes) > 0 {
lat, loss, err := p.pingNode(publicProbeNodes[0].NodeID, probeTarget.Host, probeTarget.Port, options)
// Unknown type: entry → public probe target.
if len(inNodes) > 0 {
lat, loss, err := p.pingNode(inNodes[0].NodeID, probeTarget.Host, probeTarget.Port, options)
if err == nil {
snap.ExitToBingLatency = lat
snap.ExitToBingLoss = loss
@@ -31,8 +31,11 @@ func TestTunnelQualityProberUsesConfiguredProbeTarget(t *testing.T) {
}
p.probeTunnel(77)
if !slices.Contains(calls, "30|speed.example.com|8443") {
t.Fatalf("expected exit probe to configured target, calls=%+v", calls)
if !slices.Contains(calls, "10|speed.example.com|8443") {
t.Fatalf("expected type 1 public probe from entry to configured target, calls=%+v", calls)
}
if slices.Contains(calls, "30|speed.example.com|8443") {
t.Fatalf("did not expect type 1 public probe from exit node, calls=%+v", calls)
}
snaps := p.GetAll()
if len(snaps) != 1 {
@@ -42,3 +45,25 @@ func TestTunnelQualityProberUsesConfiguredProbeTarget(t *testing.T) {
t.Fatalf("unexpected snapshot target metadata: %+v", snaps[0])
}
}
func TestTunnelQualityProberStoresProbeTargetWhenChainIncomplete(t *testing.T) {
h := setupProbeTargetTunnelHandler(t)
seedProbeTargetTunnel(t, h, 78, "quality-target-incomplete", "speed.example.com", 8443)
if err := h.repo.DB().Exec(`DELETE FROM chain_tunnel WHERE tunnel_id = ?`, 78).Error; err != nil {
t.Fatalf("delete chain rows: %v", err)
}
p := newTunnelQualityProber(h)
p.probeTunnel(78)
snaps := p.GetAll()
if len(snaps) != 1 {
t.Fatalf("expected one quality snapshot, got %+v", snaps)
}
if snaps[0].ErrorMessage == "" {
t.Fatalf("expected incomplete chain error, got %+v", snaps[0])
}
if snaps[0].ProbeTargetHost != "speed.example.com" || snaps[0].ProbeTargetPort != 8443 {
t.Fatalf("unexpected snapshot target metadata: %+v", snaps[0])
}
}