mirror of
https://github.com/SagerNet/sing-box.git
synced 2026-05-13 13:57:05 +00:00
tools: Tailscale status
This commit is contained in:
parent
eade67726a
commit
524578a635
10 changed files with 523 additions and 176 deletions
16
protocol/tailscale/hostinfo_tvos.go
Normal file
16
protocol/tailscale/hostinfo_tvos.go
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
//go:build with_gvisor && tvos
|
||||
|
||||
package tailscale
|
||||
|
||||
import (
|
||||
_ "unsafe"
|
||||
|
||||
"github.com/sagernet/tailscale/types/lazy"
|
||||
)
|
||||
|
||||
//go:linkname isAppleTV github.com/sagernet/tailscale/version.isAppleTV
|
||||
var isAppleTV lazy.SyncValue[bool]
|
||||
|
||||
func init() {
|
||||
isAppleTV.Set(true)
|
||||
}
|
||||
55
protocol/tailscale/ping.go
Normal file
55
protocol/tailscale/ping.go
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
//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,
|
||||
}
|
||||
}
|
||||
|
|
@ -4,14 +4,14 @@ package tailscale
|
|||
|
||||
import (
|
||||
"context"
|
||||
"slices"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/tailscale/ipn"
|
||||
"github.com/sagernet/tailscale/ipn/ipnstate"
|
||||
"github.com/sagernet/tailscale/tailcfg"
|
||||
)
|
||||
|
||||
var _ adapter.TailscaleStatusProvider = (*Endpoint)(nil)
|
||||
var _ adapter.TailscaleEndpoint = (*Endpoint)(nil)
|
||||
|
||||
func (t *Endpoint) SubscribeTailscaleStatus(ctx context.Context, fn func(*adapter.TailscaleEndpointStatus)) error {
|
||||
localBackend := t.server.ExportLocalBackend()
|
||||
|
|
@ -46,13 +46,35 @@ func convertTailscaleStatus(status *ipnstate.Status) *adapter.TailscaleEndpointS
|
|||
if status.Self != nil {
|
||||
result.Self = convertTailscalePeer(status.Self)
|
||||
}
|
||||
result.Users = make(map[int64]*adapter.TailscaleUser, len(status.User))
|
||||
for userID, profile := range status.User {
|
||||
result.Users[int64(userID)] = convertTailscaleUser(userID, profile)
|
||||
groupIndex := make(map[int64]*adapter.TailscaleUserGroup)
|
||||
for _, peerKey := range status.Peers() {
|
||||
peer := status.Peer[peerKey]
|
||||
userID := int64(peer.UserID)
|
||||
group, loaded := groupIndex[userID]
|
||||
if !loaded {
|
||||
group = &adapter.TailscaleUserGroup{
|
||||
UserID: userID,
|
||||
}
|
||||
if profile, hasProfile := status.User[peer.UserID]; hasProfile {
|
||||
group.LoginName = profile.LoginName
|
||||
group.DisplayName = profile.DisplayName
|
||||
group.ProfilePicURL = profile.ProfilePicURL
|
||||
}
|
||||
groupIndex[userID] = group
|
||||
result.UserGroups = append(result.UserGroups, group)
|
||||
}
|
||||
group.Peers = append(group.Peers, convertTailscalePeer(peer))
|
||||
}
|
||||
result.Peers = make([]*adapter.TailscalePeer, 0, len(status.Peer))
|
||||
for _, peer := range status.Peer {
|
||||
result.Peers = append(result.Peers, convertTailscalePeer(peer))
|
||||
for _, group := range result.UserGroups {
|
||||
slices.SortStableFunc(group.Peers, func(a, b *adapter.TailscalePeer) int {
|
||||
if a.Online != b.Online {
|
||||
if a.Online {
|
||||
return -1
|
||||
}
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
})
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
|
@ -81,12 +103,3 @@ func convertTailscalePeer(peer *ipnstate.PeerStatus) *adapter.TailscalePeer {
|
|||
KeyExpiry: keyExpiry,
|
||||
}
|
||||
}
|
||||
|
||||
func convertTailscaleUser(id tailcfg.UserID, profile tailcfg.UserProfile) *adapter.TailscaleUser {
|
||||
return &adapter.TailscaleUser{
|
||||
ID: int64(id),
|
||||
LoginName: profile.LoginName,
|
||||
DisplayName: profile.DisplayName,
|
||||
ProfilePicURL: profile.ProfilePicURL,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue