mirror of
https://github.com/SagerNet/sing-box.git
synced 2026-04-11 17:47:20 +10:00
tools: Tailscale status
This commit is contained in:
92
protocol/tailscale/status.go
Normal file
92
protocol/tailscale/status.go
Normal file
@@ -0,0 +1,92 @@
|
||||
//go:build with_gvisor
|
||||
|
||||
package tailscale
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"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)
|
||||
|
||||
func (t *Endpoint) SubscribeTailscaleStatus(ctx context.Context, fn func(*adapter.TailscaleEndpointStatus)) error {
|
||||
localBackend := t.server.ExportLocalBackend()
|
||||
sendStatus := func() {
|
||||
status := localBackend.Status()
|
||||
fn(convertTailscaleStatus(status))
|
||||
}
|
||||
sendStatus()
|
||||
localBackend.WatchNotifications(ctx, ipn.NotifyInitialState|ipn.NotifyInitialNetMap|ipn.NotifyRateLimit, nil, func(roNotify *ipn.Notify) (keepGoing bool) {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return false
|
||||
default:
|
||||
}
|
||||
if roNotify.State != nil || roNotify.NetMap != nil || roNotify.BrowseToURL != nil {
|
||||
sendStatus()
|
||||
}
|
||||
return true
|
||||
})
|
||||
return ctx.Err()
|
||||
}
|
||||
|
||||
func convertTailscaleStatus(status *ipnstate.Status) *adapter.TailscaleEndpointStatus {
|
||||
result := &adapter.TailscaleEndpointStatus{
|
||||
BackendState: status.BackendState,
|
||||
AuthURL: status.AuthURL,
|
||||
}
|
||||
if status.CurrentTailnet != nil {
|
||||
result.NetworkName = status.CurrentTailnet.Name
|
||||
result.MagicDNSSuffix = status.CurrentTailnet.MagicDNSSuffix
|
||||
}
|
||||
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)
|
||||
}
|
||||
result.Peers = make([]*adapter.TailscalePeer, 0, len(status.Peer))
|
||||
for _, peer := range status.Peer {
|
||||
result.Peers = append(result.Peers, convertTailscalePeer(peer))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func convertTailscalePeer(peer *ipnstate.PeerStatus) *adapter.TailscalePeer {
|
||||
ips := make([]string, len(peer.TailscaleIPs))
|
||||
for i, ip := range peer.TailscaleIPs {
|
||||
ips[i] = ip.String()
|
||||
}
|
||||
var keyExpiry int64
|
||||
if peer.KeyExpiry != nil {
|
||||
keyExpiry = peer.KeyExpiry.Unix()
|
||||
}
|
||||
return &adapter.TailscalePeer{
|
||||
HostName: peer.HostName,
|
||||
DNSName: peer.DNSName,
|
||||
OS: peer.OS,
|
||||
TailscaleIPs: ips,
|
||||
Online: peer.Online,
|
||||
ExitNode: peer.ExitNode,
|
||||
ExitNodeOption: peer.ExitNodeOption,
|
||||
Active: peer.Active,
|
||||
RxBytes: peer.RxBytes,
|
||||
TxBytes: peer.TxBytes,
|
||||
UserID: int64(peer.UserID),
|
||||
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,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user