#1748·nebula

BUG: 当对等体仅通过中继可访问时,会出现单向黑洞(HostInfo.remote 信息永远无法清除)

作者: JesseSchultzRiv创建于 2026年6月5日更新于 2026年6月15日

根本原因(两个相互作用的不变量)

  1. sendNoMetricsinside.go 中优先使用直接路径而不是中继路径,只要 hostinfo.remote.IsValid() 为真。如果直接路径已死,就不会回退到中继路径:
go
useRelay := !remote.IsValid() && !hostinfo.remote.IsValid()
...
if remote.IsValid() {
    err = f.writers[q].WriteTo(out, remote)
} else if hostinfo.remote.IsValid() {
    err = f.writers[q].WriteTo(out, hostinfo.remote)  // 锁定到已死的下层
} else {
    // 尝试通过中继路径发送
    ...
}
  1. handleHostRoamingoutside.go 中仅在非中继的入站包中更新 hostinfo.remote
go
func (f *Interface) handleHostRoaming(hostinfo *HostInfo, via ViaSender) {
    if !via.IsRelayed && hostinfo.remote != via.UdpAddr {
        ...
        hostinfo.SetRemote(via.UdpAddr)
    }
}

中继包仍然调用 connectionManager.In(hostinfo),因此仅从中继流量来看,隧道被认为仍然活跃着。