mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-09-15 21:00:27 +00:00
tools: Tailscale status
This commit is contained in:
@@ -0,0 +1,39 @@
|
|||||||
|
package adapter
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
|
type TailscaleStatusProvider interface {
|
||||||
|
SubscribeTailscaleStatus(ctx context.Context, fn func(*TailscaleEndpointStatus)) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type TailscaleEndpointStatus struct {
|
||||||
|
BackendState string
|
||||||
|
AuthURL string
|
||||||
|
NetworkName string
|
||||||
|
MagicDNSSuffix string
|
||||||
|
Self *TailscalePeer
|
||||||
|
Users map[int64]*TailscaleUser
|
||||||
|
Peers []*TailscalePeer
|
||||||
|
}
|
||||||
|
|
||||||
|
type TailscalePeer struct {
|
||||||
|
HostName string
|
||||||
|
DNSName string
|
||||||
|
OS string
|
||||||
|
TailscaleIPs []string
|
||||||
|
Online bool
|
||||||
|
ExitNode bool
|
||||||
|
ExitNodeOption bool
|
||||||
|
Active bool
|
||||||
|
RxBytes int64
|
||||||
|
TxBytes int64
|
||||||
|
UserID int64
|
||||||
|
KeyExpiry int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type TailscaleUser struct {
|
||||||
|
ID int64
|
||||||
|
LoginName string
|
||||||
|
DisplayName string
|
||||||
|
ProfilePicURL string
|
||||||
|
}
|
||||||
+139
-1
@@ -6,12 +6,14 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
"github.com/sagernet/sing-box/common/dialer"
|
"github.com/sagernet/sing-box/common/dialer"
|
||||||
"github.com/sagernet/sing-box/common/networkquality"
|
"github.com/sagernet/sing-box/common/networkquality"
|
||||||
"github.com/sagernet/sing-box/common/stun"
|
"github.com/sagernet/sing-box/common/stun"
|
||||||
"github.com/sagernet/sing-box/common/urltest"
|
"github.com/sagernet/sing-box/common/urltest"
|
||||||
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing-box/experimental/clashapi"
|
"github.com/sagernet/sing-box/experimental/clashapi"
|
||||||
"github.com/sagernet/sing-box/experimental/clashapi/trafficontrol"
|
"github.com/sagernet/sing-box/experimental/clashapi/trafficontrol"
|
||||||
"github.com/sagernet/sing-box/experimental/deprecated"
|
"github.com/sagernet/sing-box/experimental/deprecated"
|
||||||
@@ -704,7 +706,7 @@ func (s *StartedService) TriggerDebugCrash(ctx context.Context, request *DebugCr
|
|||||||
switch request.Type {
|
switch request.Type {
|
||||||
case DebugCrashRequest_GO:
|
case DebugCrashRequest_GO:
|
||||||
time.AfterFunc(200*time.Millisecond, func() {
|
time.AfterFunc(200*time.Millisecond, func() {
|
||||||
panic("debug go crash")
|
*(*int)(unsafe.Pointer(uintptr(0))) = 0
|
||||||
})
|
})
|
||||||
case DebugCrashRequest_NATIVE:
|
case DebugCrashRequest_NATIVE:
|
||||||
err := s.handler.TriggerNativeCrash()
|
err := s.handler.TriggerNativeCrash()
|
||||||
@@ -1284,6 +1286,142 @@ func (s *StartedService) StartSTUNTest(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *StartedService) SubscribeTailscaleStatus(
|
||||||
|
_ *emptypb.Empty,
|
||||||
|
server grpc.ServerStreamingServer[TailscaleStatusUpdate],
|
||||||
|
) error {
|
||||||
|
err := s.waitForStarted(server.Context())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
s.serviceAccess.RLock()
|
||||||
|
boxService := s.instance
|
||||||
|
s.serviceAccess.RUnlock()
|
||||||
|
|
||||||
|
endpointManager := service.FromContext[adapter.EndpointManager](boxService.ctx)
|
||||||
|
if endpointManager == nil {
|
||||||
|
return status.Error(codes.FailedPrecondition, "endpoint manager not available")
|
||||||
|
}
|
||||||
|
|
||||||
|
type tailscaleEndpoint struct {
|
||||||
|
tag string
|
||||||
|
provider adapter.TailscaleStatusProvider
|
||||||
|
}
|
||||||
|
var endpoints []tailscaleEndpoint
|
||||||
|
for _, endpoint := range endpointManager.Endpoints() {
|
||||||
|
if endpoint.Type() != C.TypeTailscale {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
provider, loaded := endpoint.(adapter.TailscaleStatusProvider)
|
||||||
|
if !loaded {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
endpoints = append(endpoints, tailscaleEndpoint{
|
||||||
|
tag: endpoint.Tag(),
|
||||||
|
provider: provider,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if len(endpoints) == 0 {
|
||||||
|
return status.Error(codes.NotFound, "no Tailscale endpoint found")
|
||||||
|
}
|
||||||
|
|
||||||
|
type taggedStatus struct {
|
||||||
|
tag string
|
||||||
|
status *adapter.TailscaleEndpointStatus
|
||||||
|
}
|
||||||
|
updates := make(chan taggedStatus, len(endpoints))
|
||||||
|
ctx, cancel := context.WithCancel(server.Context())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
var waitGroup sync.WaitGroup
|
||||||
|
for _, endpoint := range endpoints {
|
||||||
|
waitGroup.Add(1)
|
||||||
|
go func(tag string, provider adapter.TailscaleStatusProvider) {
|
||||||
|
defer waitGroup.Done()
|
||||||
|
_ = provider.SubscribeTailscaleStatus(ctx, func(endpointStatus *adapter.TailscaleEndpointStatus) {
|
||||||
|
select {
|
||||||
|
case updates <- taggedStatus{tag: tag, status: endpointStatus}:
|
||||||
|
case <-ctx.Done():
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}(endpoint.tag, endpoint.provider)
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
waitGroup.Wait()
|
||||||
|
close(updates)
|
||||||
|
}()
|
||||||
|
|
||||||
|
statuses := make(map[string]*adapter.TailscaleEndpointStatus, len(endpoints))
|
||||||
|
for update := range updates {
|
||||||
|
statuses[update.tag] = update.status
|
||||||
|
protoEndpoints := make([]*TailscaleEndpointStatus, 0, len(statuses))
|
||||||
|
for tag, endpointStatus := range statuses {
|
||||||
|
protoEndpoints = append(protoEndpoints, tailscaleEndpointStatusToProto(tag, endpointStatus))
|
||||||
|
}
|
||||||
|
sendErr := server.Send(&TailscaleStatusUpdate{
|
||||||
|
Endpoints: protoEndpoints,
|
||||||
|
})
|
||||||
|
if sendErr != nil {
|
||||||
|
return sendErr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func tailscaleEndpointStatusToProto(tag string, s *adapter.TailscaleEndpointStatus) *TailscaleEndpointStatus {
|
||||||
|
userGroupMap := make(map[int64]*TailscaleUserGroup)
|
||||||
|
for userID, user := range s.Users {
|
||||||
|
userGroupMap[userID] = &TailscaleUserGroup{
|
||||||
|
UserID: userID,
|
||||||
|
LoginName: user.LoginName,
|
||||||
|
DisplayName: user.DisplayName,
|
||||||
|
ProfilePicURL: user.ProfilePicURL,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, peer := range s.Peers {
|
||||||
|
protoPeer := tailscalePeerToProto(peer)
|
||||||
|
group, loaded := userGroupMap[peer.UserID]
|
||||||
|
if !loaded {
|
||||||
|
group = &TailscaleUserGroup{UserID: peer.UserID}
|
||||||
|
userGroupMap[peer.UserID] = group
|
||||||
|
}
|
||||||
|
group.Peers = append(group.Peers, protoPeer)
|
||||||
|
}
|
||||||
|
userGroups := make([]*TailscaleUserGroup, 0, len(userGroupMap))
|
||||||
|
for _, group := range userGroupMap {
|
||||||
|
userGroups = append(userGroups, group)
|
||||||
|
}
|
||||||
|
result := &TailscaleEndpointStatus{
|
||||||
|
EndpointTag: tag,
|
||||||
|
BackendState: s.BackendState,
|
||||||
|
AuthURL: s.AuthURL,
|
||||||
|
NetworkName: s.NetworkName,
|
||||||
|
MagicDNSSuffix: s.MagicDNSSuffix,
|
||||||
|
UserGroups: userGroups,
|
||||||
|
}
|
||||||
|
if s.Self != nil {
|
||||||
|
result.Self = tailscalePeerToProto(s.Self)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func tailscalePeerToProto(peer *adapter.TailscalePeer) *TailscalePeer {
|
||||||
|
return &TailscalePeer{
|
||||||
|
HostName: peer.HostName,
|
||||||
|
DnsName: peer.DNSName,
|
||||||
|
Os: peer.OS,
|
||||||
|
TailscaleIPs: peer.TailscaleIPs,
|
||||||
|
Online: peer.Online,
|
||||||
|
ExitNode: peer.ExitNode,
|
||||||
|
ExitNodeOption: peer.ExitNodeOption,
|
||||||
|
Active: peer.Active,
|
||||||
|
RxBytes: peer.RxBytes,
|
||||||
|
TxBytes: peer.TxBytes,
|
||||||
|
KeyExpiry: peer.KeyExpiry,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (s *StartedService) mustEmbedUnimplementedStartedServiceServer() {
|
func (s *StartedService) mustEmbedUnimplementedStartedServiceServer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+448
-70
@@ -2248,6 +2248,342 @@ func (x *STUNTestProgress) GetNatTypeSupported() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TailscaleStatusUpdate struct {
|
||||||
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
|
Endpoints []*TailscaleEndpointStatus `protobuf:"bytes,1,rep,name=endpoints,proto3" json:"endpoints,omitempty"`
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscaleStatusUpdate) Reset() {
|
||||||
|
*x = TailscaleStatusUpdate{}
|
||||||
|
mi := &file_daemon_started_service_proto_msgTypes[31]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscaleStatusUpdate) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*TailscaleStatusUpdate) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *TailscaleStatusUpdate) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_daemon_started_service_proto_msgTypes[31]
|
||||||
|
if x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use TailscaleStatusUpdate.ProtoReflect.Descriptor instead.
|
||||||
|
func (*TailscaleStatusUpdate) Descriptor() ([]byte, []int) {
|
||||||
|
return file_daemon_started_service_proto_rawDescGZIP(), []int{31}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscaleStatusUpdate) GetEndpoints() []*TailscaleEndpointStatus {
|
||||||
|
if x != nil {
|
||||||
|
return x.Endpoints
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type TailscaleEndpointStatus struct {
|
||||||
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
|
EndpointTag string `protobuf:"bytes,1,opt,name=endpointTag,proto3" json:"endpointTag,omitempty"`
|
||||||
|
BackendState string `protobuf:"bytes,2,opt,name=backendState,proto3" json:"backendState,omitempty"`
|
||||||
|
AuthURL string `protobuf:"bytes,3,opt,name=authURL,proto3" json:"authURL,omitempty"`
|
||||||
|
NetworkName string `protobuf:"bytes,4,opt,name=networkName,proto3" json:"networkName,omitempty"`
|
||||||
|
MagicDNSSuffix string `protobuf:"bytes,5,opt,name=magicDNSSuffix,proto3" json:"magicDNSSuffix,omitempty"`
|
||||||
|
Self *TailscalePeer `protobuf:"bytes,6,opt,name=self,proto3" json:"self,omitempty"`
|
||||||
|
UserGroups []*TailscaleUserGroup `protobuf:"bytes,7,rep,name=userGroups,proto3" json:"userGroups,omitempty"`
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscaleEndpointStatus) Reset() {
|
||||||
|
*x = TailscaleEndpointStatus{}
|
||||||
|
mi := &file_daemon_started_service_proto_msgTypes[32]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscaleEndpointStatus) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*TailscaleEndpointStatus) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *TailscaleEndpointStatus) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_daemon_started_service_proto_msgTypes[32]
|
||||||
|
if x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use TailscaleEndpointStatus.ProtoReflect.Descriptor instead.
|
||||||
|
func (*TailscaleEndpointStatus) Descriptor() ([]byte, []int) {
|
||||||
|
return file_daemon_started_service_proto_rawDescGZIP(), []int{32}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscaleEndpointStatus) GetEndpointTag() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.EndpointTag
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscaleEndpointStatus) GetBackendState() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.BackendState
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscaleEndpointStatus) GetAuthURL() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.AuthURL
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscaleEndpointStatus) GetNetworkName() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.NetworkName
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscaleEndpointStatus) GetMagicDNSSuffix() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.MagicDNSSuffix
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscaleEndpointStatus) GetSelf() *TailscalePeer {
|
||||||
|
if x != nil {
|
||||||
|
return x.Self
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscaleEndpointStatus) GetUserGroups() []*TailscaleUserGroup {
|
||||||
|
if x != nil {
|
||||||
|
return x.UserGroups
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type TailscaleUserGroup struct {
|
||||||
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
|
UserID int64 `protobuf:"varint,1,opt,name=userID,proto3" json:"userID,omitempty"`
|
||||||
|
LoginName string `protobuf:"bytes,2,opt,name=loginName,proto3" json:"loginName,omitempty"`
|
||||||
|
DisplayName string `protobuf:"bytes,3,opt,name=displayName,proto3" json:"displayName,omitempty"`
|
||||||
|
ProfilePicURL string `protobuf:"bytes,4,opt,name=profilePicURL,proto3" json:"profilePicURL,omitempty"`
|
||||||
|
Peers []*TailscalePeer `protobuf:"bytes,5,rep,name=peers,proto3" json:"peers,omitempty"`
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscaleUserGroup) Reset() {
|
||||||
|
*x = TailscaleUserGroup{}
|
||||||
|
mi := &file_daemon_started_service_proto_msgTypes[33]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscaleUserGroup) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*TailscaleUserGroup) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *TailscaleUserGroup) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_daemon_started_service_proto_msgTypes[33]
|
||||||
|
if x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use TailscaleUserGroup.ProtoReflect.Descriptor instead.
|
||||||
|
func (*TailscaleUserGroup) Descriptor() ([]byte, []int) {
|
||||||
|
return file_daemon_started_service_proto_rawDescGZIP(), []int{33}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscaleUserGroup) GetUserID() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.UserID
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscaleUserGroup) GetLoginName() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.LoginName
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscaleUserGroup) GetDisplayName() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.DisplayName
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscaleUserGroup) GetProfilePicURL() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.ProfilePicURL
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscaleUserGroup) GetPeers() []*TailscalePeer {
|
||||||
|
if x != nil {
|
||||||
|
return x.Peers
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type TailscalePeer struct {
|
||||||
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
|
HostName string `protobuf:"bytes,1,opt,name=hostName,proto3" json:"hostName,omitempty"`
|
||||||
|
DnsName string `protobuf:"bytes,2,opt,name=dnsName,proto3" json:"dnsName,omitempty"`
|
||||||
|
Os string `protobuf:"bytes,3,opt,name=os,proto3" json:"os,omitempty"`
|
||||||
|
TailscaleIPs []string `protobuf:"bytes,4,rep,name=tailscaleIPs,proto3" json:"tailscaleIPs,omitempty"`
|
||||||
|
Online bool `protobuf:"varint,5,opt,name=online,proto3" json:"online,omitempty"`
|
||||||
|
ExitNode bool `protobuf:"varint,6,opt,name=exitNode,proto3" json:"exitNode,omitempty"`
|
||||||
|
ExitNodeOption bool `protobuf:"varint,7,opt,name=exitNodeOption,proto3" json:"exitNodeOption,omitempty"`
|
||||||
|
Active bool `protobuf:"varint,8,opt,name=active,proto3" json:"active,omitempty"`
|
||||||
|
RxBytes int64 `protobuf:"varint,9,opt,name=rxBytes,proto3" json:"rxBytes,omitempty"`
|
||||||
|
TxBytes int64 `protobuf:"varint,10,opt,name=txBytes,proto3" json:"txBytes,omitempty"`
|
||||||
|
KeyExpiry int64 `protobuf:"varint,11,opt,name=keyExpiry,proto3" json:"keyExpiry,omitempty"`
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscalePeer) Reset() {
|
||||||
|
*x = TailscalePeer{}
|
||||||
|
mi := &file_daemon_started_service_proto_msgTypes[34]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscalePeer) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*TailscalePeer) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *TailscalePeer) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_daemon_started_service_proto_msgTypes[34]
|
||||||
|
if x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use TailscalePeer.ProtoReflect.Descriptor instead.
|
||||||
|
func (*TailscalePeer) Descriptor() ([]byte, []int) {
|
||||||
|
return file_daemon_started_service_proto_rawDescGZIP(), []int{34}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscalePeer) GetHostName() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.HostName
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscalePeer) GetDnsName() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.DnsName
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscalePeer) GetOs() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Os
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscalePeer) GetTailscaleIPs() []string {
|
||||||
|
if x != nil {
|
||||||
|
return x.TailscaleIPs
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscalePeer) GetOnline() bool {
|
||||||
|
if x != nil {
|
||||||
|
return x.Online
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscalePeer) GetExitNode() bool {
|
||||||
|
if x != nil {
|
||||||
|
return x.ExitNode
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscalePeer) GetExitNodeOption() bool {
|
||||||
|
if x != nil {
|
||||||
|
return x.ExitNodeOption
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscalePeer) GetActive() bool {
|
||||||
|
if x != nil {
|
||||||
|
return x.Active
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscalePeer) GetRxBytes() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.RxBytes
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscalePeer) GetTxBytes() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.TxBytes
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *TailscalePeer) GetKeyExpiry() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.KeyExpiry
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
type Log_Message struct {
|
type Log_Message struct {
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
Level LogLevel `protobuf:"varint,1,opt,name=level,proto3,enum=daemon.LogLevel" json:"level,omitempty"`
|
Level LogLevel `protobuf:"varint,1,opt,name=level,proto3,enum=daemon.LogLevel" json:"level,omitempty"`
|
||||||
@@ -2258,7 +2594,7 @@ type Log_Message struct {
|
|||||||
|
|
||||||
func (x *Log_Message) Reset() {
|
func (x *Log_Message) Reset() {
|
||||||
*x = Log_Message{}
|
*x = Log_Message{}
|
||||||
mi := &file_daemon_started_service_proto_msgTypes[31]
|
mi := &file_daemon_started_service_proto_msgTypes[35]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -2270,7 +2606,7 @@ func (x *Log_Message) String() string {
|
|||||||
func (*Log_Message) ProtoMessage() {}
|
func (*Log_Message) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *Log_Message) ProtoReflect() protoreflect.Message {
|
func (x *Log_Message) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_daemon_started_service_proto_msgTypes[31]
|
mi := &file_daemon_started_service_proto_msgTypes[35]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -2472,7 +2808,38 @@ const file_daemon_started_service_proto_rawDesc = "" +
|
|||||||
"\fnatFiltering\x18\x05 \x01(\x05R\fnatFiltering\x12\x18\n" +
|
"\fnatFiltering\x18\x05 \x01(\x05R\fnatFiltering\x12\x18\n" +
|
||||||
"\aisFinal\x18\x06 \x01(\bR\aisFinal\x12\x14\n" +
|
"\aisFinal\x18\x06 \x01(\bR\aisFinal\x12\x14\n" +
|
||||||
"\x05error\x18\a \x01(\tR\x05error\x12*\n" +
|
"\x05error\x18\a \x01(\tR\x05error\x12*\n" +
|
||||||
"\x10natTypeSupported\x18\b \x01(\bR\x10natTypeSupported*U\n" +
|
"\x10natTypeSupported\x18\b \x01(\bR\x10natTypeSupported\"V\n" +
|
||||||
|
"\x15TailscaleStatusUpdate\x12=\n" +
|
||||||
|
"\tendpoints\x18\x01 \x03(\v2\x1f.daemon.TailscaleEndpointStatusR\tendpoints\"\xaa\x02\n" +
|
||||||
|
"\x17TailscaleEndpointStatus\x12 \n" +
|
||||||
|
"\vendpointTag\x18\x01 \x01(\tR\vendpointTag\x12\"\n" +
|
||||||
|
"\fbackendState\x18\x02 \x01(\tR\fbackendState\x12\x18\n" +
|
||||||
|
"\aauthURL\x18\x03 \x01(\tR\aauthURL\x12 \n" +
|
||||||
|
"\vnetworkName\x18\x04 \x01(\tR\vnetworkName\x12&\n" +
|
||||||
|
"\x0emagicDNSSuffix\x18\x05 \x01(\tR\x0emagicDNSSuffix\x12)\n" +
|
||||||
|
"\x04self\x18\x06 \x01(\v2\x15.daemon.TailscalePeerR\x04self\x12:\n" +
|
||||||
|
"\n" +
|
||||||
|
"userGroups\x18\a \x03(\v2\x1a.daemon.TailscaleUserGroupR\n" +
|
||||||
|
"userGroups\"\xbf\x01\n" +
|
||||||
|
"\x12TailscaleUserGroup\x12\x16\n" +
|
||||||
|
"\x06userID\x18\x01 \x01(\x03R\x06userID\x12\x1c\n" +
|
||||||
|
"\tloginName\x18\x02 \x01(\tR\tloginName\x12 \n" +
|
||||||
|
"\vdisplayName\x18\x03 \x01(\tR\vdisplayName\x12$\n" +
|
||||||
|
"\rprofilePicURL\x18\x04 \x01(\tR\rprofilePicURL\x12+\n" +
|
||||||
|
"\x05peers\x18\x05 \x03(\v2\x15.daemon.TailscalePeerR\x05peers\"\xbf\x02\n" +
|
||||||
|
"\rTailscalePeer\x12\x1a\n" +
|
||||||
|
"\bhostName\x18\x01 \x01(\tR\bhostName\x12\x18\n" +
|
||||||
|
"\adnsName\x18\x02 \x01(\tR\adnsName\x12\x0e\n" +
|
||||||
|
"\x02os\x18\x03 \x01(\tR\x02os\x12\"\n" +
|
||||||
|
"\ftailscaleIPs\x18\x04 \x03(\tR\ftailscaleIPs\x12\x16\n" +
|
||||||
|
"\x06online\x18\x05 \x01(\bR\x06online\x12\x1a\n" +
|
||||||
|
"\bexitNode\x18\x06 \x01(\bR\bexitNode\x12&\n" +
|
||||||
|
"\x0eexitNodeOption\x18\a \x01(\bR\x0eexitNodeOption\x12\x16\n" +
|
||||||
|
"\x06active\x18\b \x01(\bR\x06active\x12\x18\n" +
|
||||||
|
"\arxBytes\x18\t \x01(\x03R\arxBytes\x12\x18\n" +
|
||||||
|
"\atxBytes\x18\n" +
|
||||||
|
" \x01(\x03R\atxBytes\x12\x1c\n" +
|
||||||
|
"\tkeyExpiry\x18\v \x01(\x03R\tkeyExpiry*U\n" +
|
||||||
"\bLogLevel\x12\t\n" +
|
"\bLogLevel\x12\t\n" +
|
||||||
"\x05PANIC\x10\x00\x12\t\n" +
|
"\x05PANIC\x10\x00\x12\t\n" +
|
||||||
"\x05FATAL\x10\x01\x12\t\n" +
|
"\x05FATAL\x10\x01\x12\t\n" +
|
||||||
@@ -2484,7 +2851,7 @@ const file_daemon_started_service_proto_rawDesc = "" +
|
|||||||
"\x13ConnectionEventType\x12\x18\n" +
|
"\x13ConnectionEventType\x12\x18\n" +
|
||||||
"\x14CONNECTION_EVENT_NEW\x10\x00\x12\x1b\n" +
|
"\x14CONNECTION_EVENT_NEW\x10\x00\x12\x1b\n" +
|
||||||
"\x17CONNECTION_EVENT_UPDATE\x10\x01\x12\x1b\n" +
|
"\x17CONNECTION_EVENT_UPDATE\x10\x01\x12\x1b\n" +
|
||||||
"\x17CONNECTION_EVENT_CLOSED\x10\x022\xac\x0f\n" +
|
"\x17CONNECTION_EVENT_CLOSED\x10\x022\x83\x10\n" +
|
||||||
"\x0eStartedService\x12=\n" +
|
"\x0eStartedService\x12=\n" +
|
||||||
"\vStopService\x12\x16.google.protobuf.Empty\x1a\x16.google.protobuf.Empty\x12?\n" +
|
"\vStopService\x12\x16.google.protobuf.Empty\x1a\x16.google.protobuf.Empty\x12?\n" +
|
||||||
"\rReloadService\x12\x16.google.protobuf.Empty\x1a\x16.google.protobuf.Empty\x12K\n" +
|
"\rReloadService\x12\x16.google.protobuf.Empty\x1a\x16.google.protobuf.Empty\x12K\n" +
|
||||||
@@ -2512,7 +2879,8 @@ const file_daemon_started_service_proto_rawDesc = "" +
|
|||||||
"\rListOutbounds\x12\x16.google.protobuf.Empty\x1a\x14.daemon.OutboundList\"\x00\x12F\n" +
|
"\rListOutbounds\x12\x16.google.protobuf.Empty\x1a\x14.daemon.OutboundList\"\x00\x12F\n" +
|
||||||
"\x12SubscribeOutbounds\x12\x16.google.protobuf.Empty\x1a\x14.daemon.OutboundList\"\x000\x01\x12d\n" +
|
"\x12SubscribeOutbounds\x12\x16.google.protobuf.Empty\x1a\x14.daemon.OutboundList\"\x000\x01\x12d\n" +
|
||||||
"\x17StartNetworkQualityTest\x12!.daemon.NetworkQualityTestRequest\x1a\".daemon.NetworkQualityTestProgress\"\x000\x01\x12F\n" +
|
"\x17StartNetworkQualityTest\x12!.daemon.NetworkQualityTestRequest\x1a\".daemon.NetworkQualityTestProgress\"\x000\x01\x12F\n" +
|
||||||
"\rStartSTUNTest\x12\x17.daemon.STUNTestRequest\x1a\x18.daemon.STUNTestProgress\"\x000\x01B%Z#github.com/sagernet/sing-box/daemonb\x06proto3"
|
"\rStartSTUNTest\x12\x17.daemon.STUNTestRequest\x1a\x18.daemon.STUNTestProgress\"\x000\x01\x12U\n" +
|
||||||
|
"\x18SubscribeTailscaleStatus\x12\x16.google.protobuf.Empty\x1a\x1d.daemon.TailscaleStatusUpdate\"\x000\x01B%Z#github.com/sagernet/sing-box/daemonb\x06proto3"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
file_daemon_started_service_proto_rawDescOnce sync.Once
|
file_daemon_started_service_proto_rawDescOnce sync.Once
|
||||||
@@ -2528,7 +2896,7 @@ func file_daemon_started_service_proto_rawDescGZIP() []byte {
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
file_daemon_started_service_proto_enumTypes = make([]protoimpl.EnumInfo, 4)
|
file_daemon_started_service_proto_enumTypes = make([]protoimpl.EnumInfo, 4)
|
||||||
file_daemon_started_service_proto_msgTypes = make([]protoimpl.MessageInfo, 32)
|
file_daemon_started_service_proto_msgTypes = make([]protoimpl.MessageInfo, 36)
|
||||||
file_daemon_started_service_proto_goTypes = []any{
|
file_daemon_started_service_proto_goTypes = []any{
|
||||||
(LogLevel)(0), // 0: daemon.LogLevel
|
(LogLevel)(0), // 0: daemon.LogLevel
|
||||||
(ConnectionEventType)(0), // 1: daemon.ConnectionEventType
|
(ConnectionEventType)(0), // 1: daemon.ConnectionEventType
|
||||||
@@ -2565,14 +2933,18 @@ var (
|
|||||||
(*NetworkQualityTestProgress)(nil), // 32: daemon.NetworkQualityTestProgress
|
(*NetworkQualityTestProgress)(nil), // 32: daemon.NetworkQualityTestProgress
|
||||||
(*STUNTestRequest)(nil), // 33: daemon.STUNTestRequest
|
(*STUNTestRequest)(nil), // 33: daemon.STUNTestRequest
|
||||||
(*STUNTestProgress)(nil), // 34: daemon.STUNTestProgress
|
(*STUNTestProgress)(nil), // 34: daemon.STUNTestProgress
|
||||||
(*Log_Message)(nil), // 35: daemon.Log.Message
|
(*TailscaleStatusUpdate)(nil), // 35: daemon.TailscaleStatusUpdate
|
||||||
(*emptypb.Empty)(nil), // 36: google.protobuf.Empty
|
(*TailscaleEndpointStatus)(nil), // 36: daemon.TailscaleEndpointStatus
|
||||||
|
(*TailscaleUserGroup)(nil), // 37: daemon.TailscaleUserGroup
|
||||||
|
(*TailscalePeer)(nil), // 38: daemon.TailscalePeer
|
||||||
|
(*Log_Message)(nil), // 39: daemon.Log.Message
|
||||||
|
(*emptypb.Empty)(nil), // 40: google.protobuf.Empty
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
var file_daemon_started_service_proto_depIdxs = []int32{
|
var file_daemon_started_service_proto_depIdxs = []int32{
|
||||||
2, // 0: daemon.ServiceStatus.status:type_name -> daemon.ServiceStatus.Type
|
2, // 0: daemon.ServiceStatus.status:type_name -> daemon.ServiceStatus.Type
|
||||||
35, // 1: daemon.Log.messages:type_name -> daemon.Log.Message
|
39, // 1: daemon.Log.messages:type_name -> daemon.Log.Message
|
||||||
0, // 2: daemon.DefaultLogLevel.level:type_name -> daemon.LogLevel
|
0, // 2: daemon.DefaultLogLevel.level:type_name -> daemon.LogLevel
|
||||||
11, // 3: daemon.Groups.group:type_name -> daemon.Group
|
11, // 3: daemon.Groups.group:type_name -> daemon.Group
|
||||||
12, // 4: daemon.Group.items:type_name -> daemon.GroupItem
|
12, // 4: daemon.Group.items:type_name -> daemon.GroupItem
|
||||||
@@ -2583,66 +2955,72 @@ var file_daemon_started_service_proto_depIdxs = []int32{
|
|||||||
25, // 9: daemon.Connection.processInfo:type_name -> daemon.ProcessInfo
|
25, // 9: daemon.Connection.processInfo:type_name -> daemon.ProcessInfo
|
||||||
28, // 10: daemon.DeprecatedWarnings.warnings:type_name -> daemon.DeprecatedWarning
|
28, // 10: daemon.DeprecatedWarnings.warnings:type_name -> daemon.DeprecatedWarning
|
||||||
12, // 11: daemon.OutboundList.outbounds:type_name -> daemon.GroupItem
|
12, // 11: daemon.OutboundList.outbounds:type_name -> daemon.GroupItem
|
||||||
0, // 12: daemon.Log.Message.level:type_name -> daemon.LogLevel
|
36, // 12: daemon.TailscaleStatusUpdate.endpoints:type_name -> daemon.TailscaleEndpointStatus
|
||||||
36, // 13: daemon.StartedService.StopService:input_type -> google.protobuf.Empty
|
38, // 13: daemon.TailscaleEndpointStatus.self:type_name -> daemon.TailscalePeer
|
||||||
36, // 14: daemon.StartedService.ReloadService:input_type -> google.protobuf.Empty
|
37, // 14: daemon.TailscaleEndpointStatus.userGroups:type_name -> daemon.TailscaleUserGroup
|
||||||
36, // 15: daemon.StartedService.SubscribeServiceStatus:input_type -> google.protobuf.Empty
|
38, // 15: daemon.TailscaleUserGroup.peers:type_name -> daemon.TailscalePeer
|
||||||
36, // 16: daemon.StartedService.SubscribeLog:input_type -> google.protobuf.Empty
|
0, // 16: daemon.Log.Message.level:type_name -> daemon.LogLevel
|
||||||
36, // 17: daemon.StartedService.GetDefaultLogLevel:input_type -> google.protobuf.Empty
|
40, // 17: daemon.StartedService.StopService:input_type -> google.protobuf.Empty
|
||||||
36, // 18: daemon.StartedService.ClearLogs:input_type -> google.protobuf.Empty
|
40, // 18: daemon.StartedService.ReloadService:input_type -> google.protobuf.Empty
|
||||||
6, // 19: daemon.StartedService.SubscribeStatus:input_type -> daemon.SubscribeStatusRequest
|
40, // 19: daemon.StartedService.SubscribeServiceStatus:input_type -> google.protobuf.Empty
|
||||||
36, // 20: daemon.StartedService.SubscribeGroups:input_type -> google.protobuf.Empty
|
40, // 20: daemon.StartedService.SubscribeLog:input_type -> google.protobuf.Empty
|
||||||
36, // 21: daemon.StartedService.GetClashModeStatus:input_type -> google.protobuf.Empty
|
40, // 21: daemon.StartedService.GetDefaultLogLevel:input_type -> google.protobuf.Empty
|
||||||
36, // 22: daemon.StartedService.SubscribeClashMode:input_type -> google.protobuf.Empty
|
40, // 22: daemon.StartedService.ClearLogs:input_type -> google.protobuf.Empty
|
||||||
16, // 23: daemon.StartedService.SetClashMode:input_type -> daemon.ClashMode
|
6, // 23: daemon.StartedService.SubscribeStatus:input_type -> daemon.SubscribeStatusRequest
|
||||||
13, // 24: daemon.StartedService.URLTest:input_type -> daemon.URLTestRequest
|
40, // 24: daemon.StartedService.SubscribeGroups:input_type -> google.protobuf.Empty
|
||||||
14, // 25: daemon.StartedService.SelectOutbound:input_type -> daemon.SelectOutboundRequest
|
40, // 25: daemon.StartedService.GetClashModeStatus:input_type -> google.protobuf.Empty
|
||||||
15, // 26: daemon.StartedService.SetGroupExpand:input_type -> daemon.SetGroupExpandRequest
|
40, // 26: daemon.StartedService.SubscribeClashMode:input_type -> google.protobuf.Empty
|
||||||
36, // 27: daemon.StartedService.GetSystemProxyStatus:input_type -> google.protobuf.Empty
|
16, // 27: daemon.StartedService.SetClashMode:input_type -> daemon.ClashMode
|
||||||
19, // 28: daemon.StartedService.SetSystemProxyEnabled:input_type -> daemon.SetSystemProxyEnabledRequest
|
13, // 28: daemon.StartedService.URLTest:input_type -> daemon.URLTestRequest
|
||||||
20, // 29: daemon.StartedService.TriggerDebugCrash:input_type -> daemon.DebugCrashRequest
|
14, // 29: daemon.StartedService.SelectOutbound:input_type -> daemon.SelectOutboundRequest
|
||||||
36, // 30: daemon.StartedService.TriggerOOMReport:input_type -> google.protobuf.Empty
|
15, // 30: daemon.StartedService.SetGroupExpand:input_type -> daemon.SetGroupExpandRequest
|
||||||
21, // 31: daemon.StartedService.SubscribeConnections:input_type -> daemon.SubscribeConnectionsRequest
|
40, // 31: daemon.StartedService.GetSystemProxyStatus:input_type -> google.protobuf.Empty
|
||||||
26, // 32: daemon.StartedService.CloseConnection:input_type -> daemon.CloseConnectionRequest
|
19, // 32: daemon.StartedService.SetSystemProxyEnabled:input_type -> daemon.SetSystemProxyEnabledRequest
|
||||||
36, // 33: daemon.StartedService.CloseAllConnections:input_type -> google.protobuf.Empty
|
20, // 33: daemon.StartedService.TriggerDebugCrash:input_type -> daemon.DebugCrashRequest
|
||||||
36, // 34: daemon.StartedService.GetDeprecatedWarnings:input_type -> google.protobuf.Empty
|
40, // 34: daemon.StartedService.TriggerOOMReport:input_type -> google.protobuf.Empty
|
||||||
36, // 35: daemon.StartedService.GetStartedAt:input_type -> google.protobuf.Empty
|
21, // 35: daemon.StartedService.SubscribeConnections:input_type -> daemon.SubscribeConnectionsRequest
|
||||||
36, // 36: daemon.StartedService.ListOutbounds:input_type -> google.protobuf.Empty
|
26, // 36: daemon.StartedService.CloseConnection:input_type -> daemon.CloseConnectionRequest
|
||||||
36, // 37: daemon.StartedService.SubscribeOutbounds:input_type -> google.protobuf.Empty
|
40, // 37: daemon.StartedService.CloseAllConnections:input_type -> google.protobuf.Empty
|
||||||
31, // 38: daemon.StartedService.StartNetworkQualityTest:input_type -> daemon.NetworkQualityTestRequest
|
40, // 38: daemon.StartedService.GetDeprecatedWarnings:input_type -> google.protobuf.Empty
|
||||||
33, // 39: daemon.StartedService.StartSTUNTest:input_type -> daemon.STUNTestRequest
|
40, // 39: daemon.StartedService.GetStartedAt:input_type -> google.protobuf.Empty
|
||||||
36, // 40: daemon.StartedService.StopService:output_type -> google.protobuf.Empty
|
40, // 40: daemon.StartedService.ListOutbounds:input_type -> google.protobuf.Empty
|
||||||
36, // 41: daemon.StartedService.ReloadService:output_type -> google.protobuf.Empty
|
40, // 41: daemon.StartedService.SubscribeOutbounds:input_type -> google.protobuf.Empty
|
||||||
4, // 42: daemon.StartedService.SubscribeServiceStatus:output_type -> daemon.ServiceStatus
|
31, // 42: daemon.StartedService.StartNetworkQualityTest:input_type -> daemon.NetworkQualityTestRequest
|
||||||
7, // 43: daemon.StartedService.SubscribeLog:output_type -> daemon.Log
|
33, // 43: daemon.StartedService.StartSTUNTest:input_type -> daemon.STUNTestRequest
|
||||||
8, // 44: daemon.StartedService.GetDefaultLogLevel:output_type -> daemon.DefaultLogLevel
|
40, // 44: daemon.StartedService.SubscribeTailscaleStatus:input_type -> google.protobuf.Empty
|
||||||
36, // 45: daemon.StartedService.ClearLogs:output_type -> google.protobuf.Empty
|
40, // 45: daemon.StartedService.StopService:output_type -> google.protobuf.Empty
|
||||||
9, // 46: daemon.StartedService.SubscribeStatus:output_type -> daemon.Status
|
40, // 46: daemon.StartedService.ReloadService:output_type -> google.protobuf.Empty
|
||||||
10, // 47: daemon.StartedService.SubscribeGroups:output_type -> daemon.Groups
|
4, // 47: daemon.StartedService.SubscribeServiceStatus:output_type -> daemon.ServiceStatus
|
||||||
17, // 48: daemon.StartedService.GetClashModeStatus:output_type -> daemon.ClashModeStatus
|
7, // 48: daemon.StartedService.SubscribeLog:output_type -> daemon.Log
|
||||||
16, // 49: daemon.StartedService.SubscribeClashMode:output_type -> daemon.ClashMode
|
8, // 49: daemon.StartedService.GetDefaultLogLevel:output_type -> daemon.DefaultLogLevel
|
||||||
36, // 50: daemon.StartedService.SetClashMode:output_type -> google.protobuf.Empty
|
40, // 50: daemon.StartedService.ClearLogs:output_type -> google.protobuf.Empty
|
||||||
36, // 51: daemon.StartedService.URLTest:output_type -> google.protobuf.Empty
|
9, // 51: daemon.StartedService.SubscribeStatus:output_type -> daemon.Status
|
||||||
36, // 52: daemon.StartedService.SelectOutbound:output_type -> google.protobuf.Empty
|
10, // 52: daemon.StartedService.SubscribeGroups:output_type -> daemon.Groups
|
||||||
36, // 53: daemon.StartedService.SetGroupExpand:output_type -> google.protobuf.Empty
|
17, // 53: daemon.StartedService.GetClashModeStatus:output_type -> daemon.ClashModeStatus
|
||||||
18, // 54: daemon.StartedService.GetSystemProxyStatus:output_type -> daemon.SystemProxyStatus
|
16, // 54: daemon.StartedService.SubscribeClashMode:output_type -> daemon.ClashMode
|
||||||
36, // 55: daemon.StartedService.SetSystemProxyEnabled:output_type -> google.protobuf.Empty
|
40, // 55: daemon.StartedService.SetClashMode:output_type -> google.protobuf.Empty
|
||||||
36, // 56: daemon.StartedService.TriggerDebugCrash:output_type -> google.protobuf.Empty
|
40, // 56: daemon.StartedService.URLTest:output_type -> google.protobuf.Empty
|
||||||
36, // 57: daemon.StartedService.TriggerOOMReport:output_type -> google.protobuf.Empty
|
40, // 57: daemon.StartedService.SelectOutbound:output_type -> google.protobuf.Empty
|
||||||
23, // 58: daemon.StartedService.SubscribeConnections:output_type -> daemon.ConnectionEvents
|
40, // 58: daemon.StartedService.SetGroupExpand:output_type -> google.protobuf.Empty
|
||||||
36, // 59: daemon.StartedService.CloseConnection:output_type -> google.protobuf.Empty
|
18, // 59: daemon.StartedService.GetSystemProxyStatus:output_type -> daemon.SystemProxyStatus
|
||||||
36, // 60: daemon.StartedService.CloseAllConnections:output_type -> google.protobuf.Empty
|
40, // 60: daemon.StartedService.SetSystemProxyEnabled:output_type -> google.protobuf.Empty
|
||||||
27, // 61: daemon.StartedService.GetDeprecatedWarnings:output_type -> daemon.DeprecatedWarnings
|
40, // 61: daemon.StartedService.TriggerDebugCrash:output_type -> google.protobuf.Empty
|
||||||
29, // 62: daemon.StartedService.GetStartedAt:output_type -> daemon.StartedAt
|
40, // 62: daemon.StartedService.TriggerOOMReport:output_type -> google.protobuf.Empty
|
||||||
30, // 63: daemon.StartedService.ListOutbounds:output_type -> daemon.OutboundList
|
23, // 63: daemon.StartedService.SubscribeConnections:output_type -> daemon.ConnectionEvents
|
||||||
30, // 64: daemon.StartedService.SubscribeOutbounds:output_type -> daemon.OutboundList
|
40, // 64: daemon.StartedService.CloseConnection:output_type -> google.protobuf.Empty
|
||||||
32, // 65: daemon.StartedService.StartNetworkQualityTest:output_type -> daemon.NetworkQualityTestProgress
|
40, // 65: daemon.StartedService.CloseAllConnections:output_type -> google.protobuf.Empty
|
||||||
34, // 66: daemon.StartedService.StartSTUNTest:output_type -> daemon.STUNTestProgress
|
27, // 66: daemon.StartedService.GetDeprecatedWarnings:output_type -> daemon.DeprecatedWarnings
|
||||||
40, // [40:67] is the sub-list for method output_type
|
29, // 67: daemon.StartedService.GetStartedAt:output_type -> daemon.StartedAt
|
||||||
13, // [13:40] is the sub-list for method input_type
|
30, // 68: daemon.StartedService.ListOutbounds:output_type -> daemon.OutboundList
|
||||||
13, // [13:13] is the sub-list for extension type_name
|
30, // 69: daemon.StartedService.SubscribeOutbounds:output_type -> daemon.OutboundList
|
||||||
13, // [13:13] is the sub-list for extension extendee
|
32, // 70: daemon.StartedService.StartNetworkQualityTest:output_type -> daemon.NetworkQualityTestProgress
|
||||||
0, // [0:13] is the sub-list for field type_name
|
34, // 71: daemon.StartedService.StartSTUNTest:output_type -> daemon.STUNTestProgress
|
||||||
|
35, // 72: daemon.StartedService.SubscribeTailscaleStatus:output_type -> daemon.TailscaleStatusUpdate
|
||||||
|
45, // [45:73] is the sub-list for method output_type
|
||||||
|
17, // [17:45] is the sub-list for method input_type
|
||||||
|
17, // [17:17] is the sub-list for extension type_name
|
||||||
|
17, // [17:17] is the sub-list for extension extendee
|
||||||
|
0, // [0:17] is the sub-list for field type_name
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { file_daemon_started_service_proto_init() }
|
func init() { file_daemon_started_service_proto_init() }
|
||||||
@@ -2656,7 +3034,7 @@ func file_daemon_started_service_proto_init() {
|
|||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_daemon_started_service_proto_rawDesc), len(file_daemon_started_service_proto_rawDesc)),
|
RawDescriptor: unsafe.Slice(unsafe.StringData(file_daemon_started_service_proto_rawDesc), len(file_daemon_started_service_proto_rawDesc)),
|
||||||
NumEnums: 4,
|
NumEnums: 4,
|
||||||
NumMessages: 32,
|
NumMessages: 36,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 1,
|
NumServices: 1,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ service StartedService {
|
|||||||
rpc SubscribeOutbounds(google.protobuf.Empty) returns (stream OutboundList) {}
|
rpc SubscribeOutbounds(google.protobuf.Empty) returns (stream OutboundList) {}
|
||||||
rpc StartNetworkQualityTest(NetworkQualityTestRequest) returns (stream NetworkQualityTestProgress) {}
|
rpc StartNetworkQualityTest(NetworkQualityTestRequest) returns (stream NetworkQualityTestProgress) {}
|
||||||
rpc StartSTUNTest(STUNTestRequest) returns (stream STUNTestProgress) {}
|
rpc StartSTUNTest(STUNTestRequest) returns (stream STUNTestProgress) {}
|
||||||
|
rpc SubscribeTailscaleStatus(google.protobuf.Empty) returns (stream TailscaleStatusUpdate) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
message ServiceStatus {
|
message ServiceStatus {
|
||||||
@@ -278,3 +279,39 @@ message STUNTestProgress {
|
|||||||
string error = 7;
|
string error = 7;
|
||||||
bool natTypeSupported = 8;
|
bool natTypeSupported = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message TailscaleStatusUpdate {
|
||||||
|
repeated TailscaleEndpointStatus endpoints = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TailscaleEndpointStatus {
|
||||||
|
string endpointTag = 1;
|
||||||
|
string backendState = 2;
|
||||||
|
string authURL = 3;
|
||||||
|
string networkName = 4;
|
||||||
|
string magicDNSSuffix = 5;
|
||||||
|
TailscalePeer self = 6;
|
||||||
|
repeated TailscaleUserGroup userGroups = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TailscaleUserGroup {
|
||||||
|
int64 userID = 1;
|
||||||
|
string loginName = 2;
|
||||||
|
string displayName = 3;
|
||||||
|
string profilePicURL = 4;
|
||||||
|
repeated TailscalePeer peers = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TailscalePeer {
|
||||||
|
string hostName = 1;
|
||||||
|
string dnsName = 2;
|
||||||
|
string os = 3;
|
||||||
|
repeated string tailscaleIPs = 4;
|
||||||
|
bool online = 5;
|
||||||
|
bool exitNode = 6;
|
||||||
|
bool exitNodeOption = 7;
|
||||||
|
bool active = 8;
|
||||||
|
int64 rxBytes = 9;
|
||||||
|
int64 txBytes = 10;
|
||||||
|
int64 keyExpiry = 11;
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,33 +15,34 @@ import (
|
|||||||
const _ = grpc.SupportPackageIsVersion9
|
const _ = grpc.SupportPackageIsVersion9
|
||||||
|
|
||||||
const (
|
const (
|
||||||
StartedService_StopService_FullMethodName = "/daemon.StartedService/StopService"
|
StartedService_StopService_FullMethodName = "/daemon.StartedService/StopService"
|
||||||
StartedService_ReloadService_FullMethodName = "/daemon.StartedService/ReloadService"
|
StartedService_ReloadService_FullMethodName = "/daemon.StartedService/ReloadService"
|
||||||
StartedService_SubscribeServiceStatus_FullMethodName = "/daemon.StartedService/SubscribeServiceStatus"
|
StartedService_SubscribeServiceStatus_FullMethodName = "/daemon.StartedService/SubscribeServiceStatus"
|
||||||
StartedService_SubscribeLog_FullMethodName = "/daemon.StartedService/SubscribeLog"
|
StartedService_SubscribeLog_FullMethodName = "/daemon.StartedService/SubscribeLog"
|
||||||
StartedService_GetDefaultLogLevel_FullMethodName = "/daemon.StartedService/GetDefaultLogLevel"
|
StartedService_GetDefaultLogLevel_FullMethodName = "/daemon.StartedService/GetDefaultLogLevel"
|
||||||
StartedService_ClearLogs_FullMethodName = "/daemon.StartedService/ClearLogs"
|
StartedService_ClearLogs_FullMethodName = "/daemon.StartedService/ClearLogs"
|
||||||
StartedService_SubscribeStatus_FullMethodName = "/daemon.StartedService/SubscribeStatus"
|
StartedService_SubscribeStatus_FullMethodName = "/daemon.StartedService/SubscribeStatus"
|
||||||
StartedService_SubscribeGroups_FullMethodName = "/daemon.StartedService/SubscribeGroups"
|
StartedService_SubscribeGroups_FullMethodName = "/daemon.StartedService/SubscribeGroups"
|
||||||
StartedService_GetClashModeStatus_FullMethodName = "/daemon.StartedService/GetClashModeStatus"
|
StartedService_GetClashModeStatus_FullMethodName = "/daemon.StartedService/GetClashModeStatus"
|
||||||
StartedService_SubscribeClashMode_FullMethodName = "/daemon.StartedService/SubscribeClashMode"
|
StartedService_SubscribeClashMode_FullMethodName = "/daemon.StartedService/SubscribeClashMode"
|
||||||
StartedService_SetClashMode_FullMethodName = "/daemon.StartedService/SetClashMode"
|
StartedService_SetClashMode_FullMethodName = "/daemon.StartedService/SetClashMode"
|
||||||
StartedService_URLTest_FullMethodName = "/daemon.StartedService/URLTest"
|
StartedService_URLTest_FullMethodName = "/daemon.StartedService/URLTest"
|
||||||
StartedService_SelectOutbound_FullMethodName = "/daemon.StartedService/SelectOutbound"
|
StartedService_SelectOutbound_FullMethodName = "/daemon.StartedService/SelectOutbound"
|
||||||
StartedService_SetGroupExpand_FullMethodName = "/daemon.StartedService/SetGroupExpand"
|
StartedService_SetGroupExpand_FullMethodName = "/daemon.StartedService/SetGroupExpand"
|
||||||
StartedService_GetSystemProxyStatus_FullMethodName = "/daemon.StartedService/GetSystemProxyStatus"
|
StartedService_GetSystemProxyStatus_FullMethodName = "/daemon.StartedService/GetSystemProxyStatus"
|
||||||
StartedService_SetSystemProxyEnabled_FullMethodName = "/daemon.StartedService/SetSystemProxyEnabled"
|
StartedService_SetSystemProxyEnabled_FullMethodName = "/daemon.StartedService/SetSystemProxyEnabled"
|
||||||
StartedService_TriggerDebugCrash_FullMethodName = "/daemon.StartedService/TriggerDebugCrash"
|
StartedService_TriggerDebugCrash_FullMethodName = "/daemon.StartedService/TriggerDebugCrash"
|
||||||
StartedService_TriggerOOMReport_FullMethodName = "/daemon.StartedService/TriggerOOMReport"
|
StartedService_TriggerOOMReport_FullMethodName = "/daemon.StartedService/TriggerOOMReport"
|
||||||
StartedService_SubscribeConnections_FullMethodName = "/daemon.StartedService/SubscribeConnections"
|
StartedService_SubscribeConnections_FullMethodName = "/daemon.StartedService/SubscribeConnections"
|
||||||
StartedService_CloseConnection_FullMethodName = "/daemon.StartedService/CloseConnection"
|
StartedService_CloseConnection_FullMethodName = "/daemon.StartedService/CloseConnection"
|
||||||
StartedService_CloseAllConnections_FullMethodName = "/daemon.StartedService/CloseAllConnections"
|
StartedService_CloseAllConnections_FullMethodName = "/daemon.StartedService/CloseAllConnections"
|
||||||
StartedService_GetDeprecatedWarnings_FullMethodName = "/daemon.StartedService/GetDeprecatedWarnings"
|
StartedService_GetDeprecatedWarnings_FullMethodName = "/daemon.StartedService/GetDeprecatedWarnings"
|
||||||
StartedService_GetStartedAt_FullMethodName = "/daemon.StartedService/GetStartedAt"
|
StartedService_GetStartedAt_FullMethodName = "/daemon.StartedService/GetStartedAt"
|
||||||
StartedService_ListOutbounds_FullMethodName = "/daemon.StartedService/ListOutbounds"
|
StartedService_ListOutbounds_FullMethodName = "/daemon.StartedService/ListOutbounds"
|
||||||
StartedService_SubscribeOutbounds_FullMethodName = "/daemon.StartedService/SubscribeOutbounds"
|
StartedService_SubscribeOutbounds_FullMethodName = "/daemon.StartedService/SubscribeOutbounds"
|
||||||
StartedService_StartNetworkQualityTest_FullMethodName = "/daemon.StartedService/StartNetworkQualityTest"
|
StartedService_StartNetworkQualityTest_FullMethodName = "/daemon.StartedService/StartNetworkQualityTest"
|
||||||
StartedService_StartSTUNTest_FullMethodName = "/daemon.StartedService/StartSTUNTest"
|
StartedService_StartSTUNTest_FullMethodName = "/daemon.StartedService/StartSTUNTest"
|
||||||
|
StartedService_SubscribeTailscaleStatus_FullMethodName = "/daemon.StartedService/SubscribeTailscaleStatus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// StartedServiceClient is the client API for StartedService service.
|
// StartedServiceClient is the client API for StartedService service.
|
||||||
@@ -75,6 +76,7 @@ type StartedServiceClient interface {
|
|||||||
SubscribeOutbounds(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (grpc.ServerStreamingClient[OutboundList], error)
|
SubscribeOutbounds(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (grpc.ServerStreamingClient[OutboundList], error)
|
||||||
StartNetworkQualityTest(ctx context.Context, in *NetworkQualityTestRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[NetworkQualityTestProgress], error)
|
StartNetworkQualityTest(ctx context.Context, in *NetworkQualityTestRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[NetworkQualityTestProgress], error)
|
||||||
StartSTUNTest(ctx context.Context, in *STUNTestRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[STUNTestProgress], error)
|
StartSTUNTest(ctx context.Context, in *STUNTestRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[STUNTestProgress], error)
|
||||||
|
SubscribeTailscaleStatus(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (grpc.ServerStreamingClient[TailscaleStatusUpdate], error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type startedServiceClient struct {
|
type startedServiceClient struct {
|
||||||
@@ -436,6 +438,25 @@ func (c *startedServiceClient) StartSTUNTest(ctx context.Context, in *STUNTestRe
|
|||||||
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
|
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
|
||||||
type StartedService_StartSTUNTestClient = grpc.ServerStreamingClient[STUNTestProgress]
|
type StartedService_StartSTUNTestClient = grpc.ServerStreamingClient[STUNTestProgress]
|
||||||
|
|
||||||
|
func (c *startedServiceClient) SubscribeTailscaleStatus(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (grpc.ServerStreamingClient[TailscaleStatusUpdate], error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
stream, err := c.cc.NewStream(ctx, &StartedService_ServiceDesc.Streams[9], StartedService_SubscribeTailscaleStatus_FullMethodName, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
x := &grpc.GenericClientStream[emptypb.Empty, TailscaleStatusUpdate]{ClientStream: stream}
|
||||||
|
if err := x.ClientStream.SendMsg(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := x.ClientStream.CloseSend(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return x, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
|
||||||
|
type StartedService_SubscribeTailscaleStatusClient = grpc.ServerStreamingClient[TailscaleStatusUpdate]
|
||||||
|
|
||||||
// StartedServiceServer is the server API for StartedService service.
|
// StartedServiceServer is the server API for StartedService service.
|
||||||
// All implementations must embed UnimplementedStartedServiceServer
|
// All implementations must embed UnimplementedStartedServiceServer
|
||||||
// for forward compatibility.
|
// for forward compatibility.
|
||||||
@@ -467,6 +488,7 @@ type StartedServiceServer interface {
|
|||||||
SubscribeOutbounds(*emptypb.Empty, grpc.ServerStreamingServer[OutboundList]) error
|
SubscribeOutbounds(*emptypb.Empty, grpc.ServerStreamingServer[OutboundList]) error
|
||||||
StartNetworkQualityTest(*NetworkQualityTestRequest, grpc.ServerStreamingServer[NetworkQualityTestProgress]) error
|
StartNetworkQualityTest(*NetworkQualityTestRequest, grpc.ServerStreamingServer[NetworkQualityTestProgress]) error
|
||||||
StartSTUNTest(*STUNTestRequest, grpc.ServerStreamingServer[STUNTestProgress]) error
|
StartSTUNTest(*STUNTestRequest, grpc.ServerStreamingServer[STUNTestProgress]) error
|
||||||
|
SubscribeTailscaleStatus(*emptypb.Empty, grpc.ServerStreamingServer[TailscaleStatusUpdate]) error
|
||||||
mustEmbedUnimplementedStartedServiceServer()
|
mustEmbedUnimplementedStartedServiceServer()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -584,6 +606,10 @@ func (UnimplementedStartedServiceServer) StartNetworkQualityTest(*NetworkQuality
|
|||||||
func (UnimplementedStartedServiceServer) StartSTUNTest(*STUNTestRequest, grpc.ServerStreamingServer[STUNTestProgress]) error {
|
func (UnimplementedStartedServiceServer) StartSTUNTest(*STUNTestRequest, grpc.ServerStreamingServer[STUNTestProgress]) error {
|
||||||
return status.Error(codes.Unimplemented, "method StartSTUNTest not implemented")
|
return status.Error(codes.Unimplemented, "method StartSTUNTest not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (UnimplementedStartedServiceServer) SubscribeTailscaleStatus(*emptypb.Empty, grpc.ServerStreamingServer[TailscaleStatusUpdate]) error {
|
||||||
|
return status.Error(codes.Unimplemented, "method SubscribeTailscaleStatus not implemented")
|
||||||
|
}
|
||||||
func (UnimplementedStartedServiceServer) mustEmbedUnimplementedStartedServiceServer() {}
|
func (UnimplementedStartedServiceServer) mustEmbedUnimplementedStartedServiceServer() {}
|
||||||
func (UnimplementedStartedServiceServer) testEmbeddedByValue() {}
|
func (UnimplementedStartedServiceServer) testEmbeddedByValue() {}
|
||||||
|
|
||||||
@@ -1028,6 +1054,17 @@ func _StartedService_StartSTUNTest_Handler(srv interface{}, stream grpc.ServerSt
|
|||||||
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
|
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
|
||||||
type StartedService_StartSTUNTestServer = grpc.ServerStreamingServer[STUNTestProgress]
|
type StartedService_StartSTUNTestServer = grpc.ServerStreamingServer[STUNTestProgress]
|
||||||
|
|
||||||
|
func _StartedService_SubscribeTailscaleStatus_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||||
|
m := new(emptypb.Empty)
|
||||||
|
if err := stream.RecvMsg(m); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return srv.(StartedServiceServer).SubscribeTailscaleStatus(m, &grpc.GenericServerStream[emptypb.Empty, TailscaleStatusUpdate]{ServerStream: stream})
|
||||||
|
}
|
||||||
|
|
||||||
|
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
|
||||||
|
type StartedService_SubscribeTailscaleStatusServer = grpc.ServerStreamingServer[TailscaleStatusUpdate]
|
||||||
|
|
||||||
// StartedService_ServiceDesc is the grpc.ServiceDesc for StartedService service.
|
// StartedService_ServiceDesc is the grpc.ServiceDesc for StartedService service.
|
||||||
// It's only intended for direct use with grpc.RegisterService,
|
// It's only intended for direct use with grpc.RegisterService,
|
||||||
// and not to be introspected or modified (even as a copy)
|
// and not to be introspected or modified (even as a copy)
|
||||||
@@ -1154,6 +1191,11 @@ var StartedService_ServiceDesc = grpc.ServiceDesc{
|
|||||||
Handler: _StartedService_StartSTUNTest_Handler,
|
Handler: _StartedService_StartSTUNTest_Handler,
|
||||||
ServerStreams: true,
|
ServerStreams: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
StreamName: "SubscribeTailscaleStatus",
|
||||||
|
Handler: _StartedService_SubscribeTailscaleStatus_Handler,
|
||||||
|
ServerStreams: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Metadata: "daemon/started_service.proto",
|
Metadata: "daemon/started_service.proto",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -720,3 +720,25 @@ func (c *CommandClient) StartSTUNTest(server string, outboundTag string, handler
|
|||||||
handler.OnProgress(stunTestProgressFromGRPC(event))
|
handler.OnProgress(stunTestProgressFromGRPC(event))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *CommandClient) SubscribeTailscaleStatus(handler TailscaleStatusHandler) error {
|
||||||
|
client, err := c.getClientForCall()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if c.standalone {
|
||||||
|
defer c.closeConnection()
|
||||||
|
}
|
||||||
|
stream, err := client.SubscribeTailscaleStatus(context.Background(), &emptypb.Empty{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
event, recvErr := stream.Recv()
|
||||||
|
if recvErr != nil {
|
||||||
|
handler.OnError(recvErr.Error())
|
||||||
|
return recvErr
|
||||||
|
}
|
||||||
|
handler.OnStatusUpdate(tailscaleStatusUpdateFromGRPC(event))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,132 @@
|
|||||||
|
package libbox
|
||||||
|
|
||||||
|
import "github.com/sagernet/sing-box/daemon"
|
||||||
|
|
||||||
|
type TailscaleStatusUpdate struct {
|
||||||
|
endpoints []*TailscaleEndpointStatus
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *TailscaleStatusUpdate) Endpoints() TailscaleEndpointStatusIterator {
|
||||||
|
return newIterator(u.endpoints)
|
||||||
|
}
|
||||||
|
|
||||||
|
type TailscaleEndpointStatusIterator interface {
|
||||||
|
Next() *TailscaleEndpointStatus
|
||||||
|
HasNext() bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type TailscaleEndpointStatus struct {
|
||||||
|
EndpointTag string
|
||||||
|
BackendState string
|
||||||
|
AuthURL string
|
||||||
|
NetworkName string
|
||||||
|
MagicDNSSuffix string
|
||||||
|
Self *TailscalePeer
|
||||||
|
userGroups []*TailscaleUserGroup
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *TailscaleEndpointStatus) UserGroups() TailscaleUserGroupIterator {
|
||||||
|
return newIterator(s.userGroups)
|
||||||
|
}
|
||||||
|
|
||||||
|
type TailscaleUserGroupIterator interface {
|
||||||
|
Next() *TailscaleUserGroup
|
||||||
|
HasNext() bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type TailscaleUserGroup struct {
|
||||||
|
UserID int64
|
||||||
|
LoginName string
|
||||||
|
DisplayName string
|
||||||
|
ProfilePicURL string
|
||||||
|
peers []*TailscalePeer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *TailscaleUserGroup) Peers() TailscalePeerIterator {
|
||||||
|
return newIterator(g.peers)
|
||||||
|
}
|
||||||
|
|
||||||
|
type TailscalePeerIterator interface {
|
||||||
|
Next() *TailscalePeer
|
||||||
|
HasNext() bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type TailscalePeer struct {
|
||||||
|
HostName string
|
||||||
|
DNSName string
|
||||||
|
OS string
|
||||||
|
tailscaleIPs []string
|
||||||
|
Online bool
|
||||||
|
ExitNode bool
|
||||||
|
ExitNodeOption bool
|
||||||
|
Active bool
|
||||||
|
RxBytes int64
|
||||||
|
TxBytes int64
|
||||||
|
KeyExpiry int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *TailscalePeer) TailscaleIPs() StringIterator {
|
||||||
|
return newIterator(p.tailscaleIPs)
|
||||||
|
}
|
||||||
|
|
||||||
|
type TailscaleStatusHandler interface {
|
||||||
|
OnStatusUpdate(status *TailscaleStatusUpdate)
|
||||||
|
OnError(message string)
|
||||||
|
}
|
||||||
|
|
||||||
|
func tailscaleStatusUpdateFromGRPC(update *daemon.TailscaleStatusUpdate) *TailscaleStatusUpdate {
|
||||||
|
endpoints := make([]*TailscaleEndpointStatus, len(update.Endpoints))
|
||||||
|
for i, endpoint := range update.Endpoints {
|
||||||
|
endpoints[i] = tailscaleEndpointStatusFromGRPC(endpoint)
|
||||||
|
}
|
||||||
|
return &TailscaleStatusUpdate{endpoints: endpoints}
|
||||||
|
}
|
||||||
|
|
||||||
|
func tailscaleEndpointStatusFromGRPC(status *daemon.TailscaleEndpointStatus) *TailscaleEndpointStatus {
|
||||||
|
userGroups := make([]*TailscaleUserGroup, len(status.UserGroups))
|
||||||
|
for i, group := range status.UserGroups {
|
||||||
|
userGroups[i] = tailscaleUserGroupFromGRPC(group)
|
||||||
|
}
|
||||||
|
result := &TailscaleEndpointStatus{
|
||||||
|
EndpointTag: status.EndpointTag,
|
||||||
|
BackendState: status.BackendState,
|
||||||
|
AuthURL: status.AuthURL,
|
||||||
|
NetworkName: status.NetworkName,
|
||||||
|
MagicDNSSuffix: status.MagicDNSSuffix,
|
||||||
|
userGroups: userGroups,
|
||||||
|
}
|
||||||
|
if status.Self != nil {
|
||||||
|
result.Self = tailscalePeerFromGRPC(status.Self)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func tailscaleUserGroupFromGRPC(group *daemon.TailscaleUserGroup) *TailscaleUserGroup {
|
||||||
|
peers := make([]*TailscalePeer, len(group.Peers))
|
||||||
|
for i, peer := range group.Peers {
|
||||||
|
peers[i] = tailscalePeerFromGRPC(peer)
|
||||||
|
}
|
||||||
|
return &TailscaleUserGroup{
|
||||||
|
UserID: group.UserID,
|
||||||
|
LoginName: group.LoginName,
|
||||||
|
DisplayName: group.DisplayName,
|
||||||
|
ProfilePicURL: group.ProfilePicURL,
|
||||||
|
peers: peers,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func tailscalePeerFromGRPC(peer *daemon.TailscalePeer) *TailscalePeer {
|
||||||
|
return &TailscalePeer{
|
||||||
|
HostName: peer.HostName,
|
||||||
|
DNSName: peer.DnsName,
|
||||||
|
OS: peer.Os,
|
||||||
|
tailscaleIPs: peer.TailscaleIPs,
|
||||||
|
Online: peer.Online,
|
||||||
|
ExitNode: peer.ExitNode,
|
||||||
|
ExitNodeOption: peer.ExitNodeOption,
|
||||||
|
Active: peer.Active,
|
||||||
|
RxBytes: peer.RxBytes,
|
||||||
|
TxBytes: peer.TxBytes,
|
||||||
|
KeyExpiry: peer.KeyExpiry,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,12 @@
|
|||||||
package libbox
|
package libbox
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
func TriggerGoPanic() {
|
func TriggerGoPanic() {
|
||||||
time.AfterFunc(200*time.Millisecond, func() {
|
time.AfterFunc(200*time.Millisecond, func() {
|
||||||
panic("debug go crash")
|
*(*int)(unsafe.Pointer(uintptr(0))) = 0
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/sagernet/sing-box/common/networkquality"
|
"github.com/sagernet/sing-box/common/networkquality"
|
||||||
"github.com/sagernet/sing-box/common/stun"
|
"github.com/sagernet/sing-box/common/stun"
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
|
"github.com/sagernet/sing-box/dns"
|
||||||
"github.com/sagernet/sing-box/experimental/locale"
|
"github.com/sagernet/sing-box/experimental/locale"
|
||||||
"github.com/sagernet/sing-box/log"
|
"github.com/sagernet/sing-box/log"
|
||||||
"github.com/sagernet/sing-box/service/oomkiller"
|
"github.com/sagernet/sing-box/service/oomkiller"
|
||||||
@@ -181,6 +182,10 @@ func FormatNATFiltering(value int32) string {
|
|||||||
return stun.NATFiltering(value).String()
|
return stun.NATFiltering(value).String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func FormatFQDN(fqdn string) string {
|
||||||
|
return dns.FqdnToDomain(fqdn)
|
||||||
|
}
|
||||||
|
|
||||||
func ProxyDisplayType(proxyType string) string {
|
func ProxyDisplayType(proxyType string) string {
|
||||||
return C.ProxyDisplayName(proxyType)
|
return C.ProxyDisplayName(proxyType)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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