Files
sing-box/protocol/tailscale/ping.go
2026-04-10 16:24:29 +08:00

56 lines
1.2 KiB
Go

//go:build with_gvisor
package tailscale
import (
"context"
"net/netip"
"time"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/tailscale/ipn/ipnstate"
"github.com/sagernet/tailscale/tailcfg"
)
func (t *Endpoint) StartTailscalePing(ctx context.Context, peerIP string, fn func(*adapter.TailscalePingResult)) error {
ip, err := netip.ParseAddr(peerIP)
if err != nil {
return err
}
localClient, err := t.server.LocalClient()
if err != nil {
return err
}
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for {
result, pingErr := localClient.Ping(ctx, ip, tailcfg.PingDisco)
if ctx.Err() != nil {
return ctx.Err()
}
if pingErr != nil {
fn(&adapter.TailscalePingResult{
Error: pingErr.Error(),
})
} else {
fn(convertPingResult(result))
}
select {
case <-ctx.Done():
return ctx.Err()
case <-ticker.C:
}
}
}
func convertPingResult(result *ipnstate.PingResult) *adapter.TailscalePingResult {
return &adapter.TailscalePingResult{
LatencyMs: result.LatencySeconds * 1000,
IsDirect: result.Endpoint != "",
Endpoint: result.Endpoint,
DERPRegionID: int32(result.DERPRegionID),
DERPRegionCode: result.DERPRegionCode,
Error: result.Err,
}
}