tailscale: Add runtime exit node API
This commit is contained in:
@@ -5,6 +5,7 @@ import "context"
|
|||||||
type TailscaleEndpoint interface {
|
type TailscaleEndpoint interface {
|
||||||
SubscribeTailscaleStatus(ctx context.Context, fn func(*TailscaleEndpointStatus)) error
|
SubscribeTailscaleStatus(ctx context.Context, fn func(*TailscaleEndpointStatus)) error
|
||||||
StartTailscalePing(ctx context.Context, peerIP string, fn func(*TailscalePingResult)) error
|
StartTailscalePing(ctx context.Context, peerIP string, fn func(*TailscalePingResult)) error
|
||||||
|
SetTailscaleExitNode(ctx context.Context, stableID string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type TailscalePingResult struct {
|
type TailscalePingResult struct {
|
||||||
@@ -22,6 +23,7 @@ type TailscaleEndpointStatus struct {
|
|||||||
NetworkName string
|
NetworkName string
|
||||||
MagicDNSSuffix string
|
MagicDNSSuffix string
|
||||||
Self *TailscalePeer
|
Self *TailscalePeer
|
||||||
|
ExitNode *TailscalePeer
|
||||||
UserGroups []*TailscaleUserGroup
|
UserGroups []*TailscaleUserGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,6 +36,7 @@ type TailscaleUserGroup struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type TailscalePeer struct {
|
type TailscalePeer struct {
|
||||||
|
StableID string
|
||||||
HostName string
|
HostName string
|
||||||
DNSName string
|
DNSName string
|
||||||
OS string
|
OS string
|
||||||
|
|||||||
@@ -1384,11 +1384,15 @@ func tailscaleEndpointStatusToProto(tag string, s *adapter.TailscaleEndpointStat
|
|||||||
if s.Self != nil {
|
if s.Self != nil {
|
||||||
result.Self = tailscalePeerToProto(s.Self)
|
result.Self = tailscalePeerToProto(s.Self)
|
||||||
}
|
}
|
||||||
|
if s.ExitNode != nil {
|
||||||
|
result.ExitNode = tailscalePeerToProto(s.ExitNode)
|
||||||
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func tailscalePeerToProto(peer *adapter.TailscalePeer) *TailscalePeer {
|
func tailscalePeerToProto(peer *adapter.TailscalePeer) *TailscalePeer {
|
||||||
return &TailscalePeer{
|
return &TailscalePeer{
|
||||||
|
StableID: peer.StableID,
|
||||||
HostName: peer.HostName,
|
HostName: peer.HostName,
|
||||||
DnsName: peer.DNSName,
|
DnsName: peer.DNSName,
|
||||||
Os: peer.OS,
|
Os: peer.OS,
|
||||||
@@ -1462,6 +1466,40 @@ func (s *StartedService) StartTailscalePing(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *StartedService) SetTailscaleExitNode(ctx context.Context, request *SetTailscaleExitNodeRequest) (*emptypb.Empty, error) {
|
||||||
|
err := s.waitForStarted(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
s.serviceAccess.RLock()
|
||||||
|
boxService := s.instance
|
||||||
|
s.serviceAccess.RUnlock()
|
||||||
|
|
||||||
|
endpointManager := service.FromContext[adapter.EndpointManager](boxService.ctx)
|
||||||
|
if endpointManager == nil {
|
||||||
|
return nil, status.Error(codes.FailedPrecondition, "endpoint manager not available")
|
||||||
|
}
|
||||||
|
if request.EndpointTag == "" {
|
||||||
|
return nil, status.Error(codes.InvalidArgument, "endpoint tag is required")
|
||||||
|
}
|
||||||
|
endpoint, loaded := endpointManager.Get(request.EndpointTag)
|
||||||
|
if !loaded {
|
||||||
|
return nil, status.Error(codes.NotFound, "endpoint not found: "+request.EndpointTag)
|
||||||
|
}
|
||||||
|
if endpoint.Type() != C.TypeTailscale {
|
||||||
|
return nil, status.Error(codes.InvalidArgument, "endpoint is not Tailscale: "+request.EndpointTag)
|
||||||
|
}
|
||||||
|
tsEndpoint, loaded := endpoint.(adapter.TailscaleEndpoint)
|
||||||
|
if !loaded {
|
||||||
|
return nil, status.Error(codes.FailedPrecondition, "endpoint does not support tailscale")
|
||||||
|
}
|
||||||
|
err = tsEndpoint.SetTailscaleExitNode(ctx, request.StableID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &emptypb.Empty{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *StartedService) mustEmbedUnimplementedStartedServiceServer() {
|
func (s *StartedService) mustEmbedUnimplementedStartedServiceServer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+155
-77
@@ -2301,6 +2301,7 @@ type TailscaleEndpointStatus struct {
|
|||||||
MagicDNSSuffix string `protobuf:"bytes,5,opt,name=magicDNSSuffix,proto3" json:"magicDNSSuffix,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"`
|
Self *TailscalePeer `protobuf:"bytes,6,opt,name=self,proto3" json:"self,omitempty"`
|
||||||
UserGroups []*TailscaleUserGroup `protobuf:"bytes,7,rep,name=userGroups,proto3" json:"userGroups,omitempty"`
|
UserGroups []*TailscaleUserGroup `protobuf:"bytes,7,rep,name=userGroups,proto3" json:"userGroups,omitempty"`
|
||||||
|
ExitNode *TailscalePeer `protobuf:"bytes,8,opt,name=exitNode,proto3" json:"exitNode,omitempty"`
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
}
|
}
|
||||||
@@ -2384,6 +2385,13 @@ func (x *TailscaleEndpointStatus) GetUserGroups() []*TailscaleUserGroup {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *TailscaleEndpointStatus) GetExitNode() *TailscalePeer {
|
||||||
|
if x != nil {
|
||||||
|
return x.ExitNode
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type TailscaleUserGroup struct {
|
type TailscaleUserGroup struct {
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
UserID int64 `protobuf:"varint,1,opt,name=userID,proto3" json:"userID,omitempty"`
|
UserID int64 `protobuf:"varint,1,opt,name=userID,proto3" json:"userID,omitempty"`
|
||||||
@@ -2473,6 +2481,7 @@ type TailscalePeer struct {
|
|||||||
RxBytes int64 `protobuf:"varint,9,opt,name=rxBytes,proto3" json:"rxBytes,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"`
|
TxBytes int64 `protobuf:"varint,10,opt,name=txBytes,proto3" json:"txBytes,omitempty"`
|
||||||
KeyExpiry int64 `protobuf:"varint,11,opt,name=keyExpiry,proto3" json:"keyExpiry,omitempty"`
|
KeyExpiry int64 `protobuf:"varint,11,opt,name=keyExpiry,proto3" json:"keyExpiry,omitempty"`
|
||||||
|
StableID string `protobuf:"bytes,12,opt,name=stableID,proto3" json:"stableID,omitempty"`
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
}
|
}
|
||||||
@@ -2584,6 +2593,13 @@ func (x *TailscalePeer) GetKeyExpiry() int64 {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *TailscalePeer) GetStableID() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.StableID
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type TailscalePingRequest struct {
|
type TailscalePingRequest struct {
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
EndpointTag string `protobuf:"bytes,1,opt,name=endpointTag,proto3" json:"endpointTag,omitempty"`
|
EndpointTag string `protobuf:"bytes,1,opt,name=endpointTag,proto3" json:"endpointTag,omitempty"`
|
||||||
@@ -2720,6 +2736,58 @@ func (x *TailscalePingResponse) GetError() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SetTailscaleExitNodeRequest struct {
|
||||||
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
|
EndpointTag string `protobuf:"bytes,1,opt,name=endpointTag,proto3" json:"endpointTag,omitempty"`
|
||||||
|
StableID string `protobuf:"bytes,2,opt,name=stableID,proto3" json:"stableID,omitempty"`
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SetTailscaleExitNodeRequest) Reset() {
|
||||||
|
*x = SetTailscaleExitNodeRequest{}
|
||||||
|
mi := &file_daemon_started_service_proto_msgTypes[37]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SetTailscaleExitNodeRequest) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*SetTailscaleExitNodeRequest) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *SetTailscaleExitNodeRequest) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_daemon_started_service_proto_msgTypes[37]
|
||||||
|
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 SetTailscaleExitNodeRequest.ProtoReflect.Descriptor instead.
|
||||||
|
func (*SetTailscaleExitNodeRequest) Descriptor() ([]byte, []int) {
|
||||||
|
return file_daemon_started_service_proto_rawDescGZIP(), []int{37}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SetTailscaleExitNodeRequest) GetEndpointTag() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.EndpointTag
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SetTailscaleExitNodeRequest) GetStableID() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.StableID
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
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"`
|
||||||
@@ -2730,7 +2798,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[37]
|
mi := &file_daemon_started_service_proto_msgTypes[38]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -2742,7 +2810,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[37]
|
mi := &file_daemon_started_service_proto_msgTypes[38]
|
||||||
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 {
|
||||||
@@ -2946,7 +3014,7 @@ const file_daemon_started_service_proto_rawDesc = "" +
|
|||||||
"\x05error\x18\a \x01(\tR\x05error\x12*\n" +
|
"\x05error\x18\a \x01(\tR\x05error\x12*\n" +
|
||||||
"\x10natTypeSupported\x18\b \x01(\bR\x10natTypeSupported\"V\n" +
|
"\x10natTypeSupported\x18\b \x01(\bR\x10natTypeSupported\"V\n" +
|
||||||
"\x15TailscaleStatusUpdate\x12=\n" +
|
"\x15TailscaleStatusUpdate\x12=\n" +
|
||||||
"\tendpoints\x18\x01 \x03(\v2\x1f.daemon.TailscaleEndpointStatusR\tendpoints\"\xaa\x02\n" +
|
"\tendpoints\x18\x01 \x03(\v2\x1f.daemon.TailscaleEndpointStatusR\tendpoints\"\xdd\x02\n" +
|
||||||
"\x17TailscaleEndpointStatus\x12 \n" +
|
"\x17TailscaleEndpointStatus\x12 \n" +
|
||||||
"\vendpointTag\x18\x01 \x01(\tR\vendpointTag\x12\"\n" +
|
"\vendpointTag\x18\x01 \x01(\tR\vendpointTag\x12\"\n" +
|
||||||
"\fbackendState\x18\x02 \x01(\tR\fbackendState\x12\x18\n" +
|
"\fbackendState\x18\x02 \x01(\tR\fbackendState\x12\x18\n" +
|
||||||
@@ -2956,13 +3024,14 @@ const file_daemon_started_service_proto_rawDesc = "" +
|
|||||||
"\x04self\x18\x06 \x01(\v2\x15.daemon.TailscalePeerR\x04self\x12:\n" +
|
"\x04self\x18\x06 \x01(\v2\x15.daemon.TailscalePeerR\x04self\x12:\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"userGroups\x18\a \x03(\v2\x1a.daemon.TailscaleUserGroupR\n" +
|
"userGroups\x18\a \x03(\v2\x1a.daemon.TailscaleUserGroupR\n" +
|
||||||
"userGroups\"\xbf\x01\n" +
|
"userGroups\x121\n" +
|
||||||
|
"\bexitNode\x18\b \x01(\v2\x15.daemon.TailscalePeerR\bexitNode\"\xbf\x01\n" +
|
||||||
"\x12TailscaleUserGroup\x12\x16\n" +
|
"\x12TailscaleUserGroup\x12\x16\n" +
|
||||||
"\x06userID\x18\x01 \x01(\x03R\x06userID\x12\x1c\n" +
|
"\x06userID\x18\x01 \x01(\x03R\x06userID\x12\x1c\n" +
|
||||||
"\tloginName\x18\x02 \x01(\tR\tloginName\x12 \n" +
|
"\tloginName\x18\x02 \x01(\tR\tloginName\x12 \n" +
|
||||||
"\vdisplayName\x18\x03 \x01(\tR\vdisplayName\x12$\n" +
|
"\vdisplayName\x18\x03 \x01(\tR\vdisplayName\x12$\n" +
|
||||||
"\rprofilePicURL\x18\x04 \x01(\tR\rprofilePicURL\x12+\n" +
|
"\rprofilePicURL\x18\x04 \x01(\tR\rprofilePicURL\x12+\n" +
|
||||||
"\x05peers\x18\x05 \x03(\v2\x15.daemon.TailscalePeerR\x05peers\"\xbf\x02\n" +
|
"\x05peers\x18\x05 \x03(\v2\x15.daemon.TailscalePeerR\x05peers\"\xdb\x02\n" +
|
||||||
"\rTailscalePeer\x12\x1a\n" +
|
"\rTailscalePeer\x12\x1a\n" +
|
||||||
"\bhostName\x18\x01 \x01(\tR\bhostName\x12\x18\n" +
|
"\bhostName\x18\x01 \x01(\tR\bhostName\x12\x18\n" +
|
||||||
"\adnsName\x18\x02 \x01(\tR\adnsName\x12\x0e\n" +
|
"\adnsName\x18\x02 \x01(\tR\adnsName\x12\x0e\n" +
|
||||||
@@ -2975,7 +3044,8 @@ const file_daemon_started_service_proto_rawDesc = "" +
|
|||||||
"\arxBytes\x18\t \x01(\x03R\arxBytes\x12\x18\n" +
|
"\arxBytes\x18\t \x01(\x03R\arxBytes\x12\x18\n" +
|
||||||
"\atxBytes\x18\n" +
|
"\atxBytes\x18\n" +
|
||||||
" \x01(\x03R\atxBytes\x12\x1c\n" +
|
" \x01(\x03R\atxBytes\x12\x1c\n" +
|
||||||
"\tkeyExpiry\x18\v \x01(\x03R\tkeyExpiry\"P\n" +
|
"\tkeyExpiry\x18\v \x01(\x03R\tkeyExpiry\x12\x1a\n" +
|
||||||
|
"\bstableID\x18\f \x01(\tR\bstableID\"P\n" +
|
||||||
"\x14TailscalePingRequest\x12 \n" +
|
"\x14TailscalePingRequest\x12 \n" +
|
||||||
"\vendpointTag\x18\x01 \x01(\tR\vendpointTag\x12\x16\n" +
|
"\vendpointTag\x18\x01 \x01(\tR\vendpointTag\x12\x16\n" +
|
||||||
"\x06peerIP\x18\x02 \x01(\tR\x06peerIP\"\xcf\x01\n" +
|
"\x06peerIP\x18\x02 \x01(\tR\x06peerIP\"\xcf\x01\n" +
|
||||||
@@ -2985,7 +3055,10 @@ const file_daemon_started_service_proto_rawDesc = "" +
|
|||||||
"\bendpoint\x18\x03 \x01(\tR\bendpoint\x12\"\n" +
|
"\bendpoint\x18\x03 \x01(\tR\bendpoint\x12\"\n" +
|
||||||
"\fderpRegionID\x18\x04 \x01(\x05R\fderpRegionID\x12&\n" +
|
"\fderpRegionID\x18\x04 \x01(\x05R\fderpRegionID\x12&\n" +
|
||||||
"\x0ederpRegionCode\x18\x05 \x01(\tR\x0ederpRegionCode\x12\x14\n" +
|
"\x0ederpRegionCode\x18\x05 \x01(\tR\x0ederpRegionCode\x12\x14\n" +
|
||||||
"\x05error\x18\x06 \x01(\tR\x05error*U\n" +
|
"\x05error\x18\x06 \x01(\tR\x05error\"[\n" +
|
||||||
|
"\x1bSetTailscaleExitNodeRequest\x12 \n" +
|
||||||
|
"\vendpointTag\x18\x01 \x01(\tR\vendpointTag\x12\x1a\n" +
|
||||||
|
"\bstableID\x18\x02 \x01(\tR\bstableID*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" +
|
||||||
@@ -2997,7 +3070,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\x99\x10\n" +
|
"\x17CONNECTION_EVENT_CLOSED\x10\x022\xf0\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" +
|
||||||
@@ -3026,7 +3099,8 @@ const file_daemon_started_service_proto_rawDesc = "" +
|
|||||||
"\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\x01\x12U\n" +
|
"\rStartSTUNTest\x12\x17.daemon.STUNTestRequest\x1a\x18.daemon.STUNTestProgress\"\x000\x01\x12U\n" +
|
||||||
"\x18SubscribeTailscaleStatus\x12\x16.google.protobuf.Empty\x1a\x1d.daemon.TailscaleStatusUpdate\"\x000\x01\x12U\n" +
|
"\x18SubscribeTailscaleStatus\x12\x16.google.protobuf.Empty\x1a\x1d.daemon.TailscaleStatusUpdate\"\x000\x01\x12U\n" +
|
||||||
"\x12StartTailscalePing\x12\x1c.daemon.TailscalePingRequest\x1a\x1d.daemon.TailscalePingResponse\"\x000\x01B%Z#github.com/sagernet/sing-box/daemonb\x06proto3"
|
"\x12StartTailscalePing\x12\x1c.daemon.TailscalePingRequest\x1a\x1d.daemon.TailscalePingResponse\"\x000\x01\x12U\n" +
|
||||||
|
"\x14SetTailscaleExitNode\x12#.daemon.SetTailscaleExitNodeRequest\x1a\x16.google.protobuf.Empty\"\x00B%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
|
||||||
@@ -3042,7 +3116,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, 38)
|
file_daemon_started_service_proto_msgTypes = make([]protoimpl.MessageInfo, 39)
|
||||||
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
|
||||||
@@ -3085,14 +3159,15 @@ var (
|
|||||||
(*TailscalePeer)(nil), // 38: daemon.TailscalePeer
|
(*TailscalePeer)(nil), // 38: daemon.TailscalePeer
|
||||||
(*TailscalePingRequest)(nil), // 39: daemon.TailscalePingRequest
|
(*TailscalePingRequest)(nil), // 39: daemon.TailscalePingRequest
|
||||||
(*TailscalePingResponse)(nil), // 40: daemon.TailscalePingResponse
|
(*TailscalePingResponse)(nil), // 40: daemon.TailscalePingResponse
|
||||||
(*Log_Message)(nil), // 41: daemon.Log.Message
|
(*SetTailscaleExitNodeRequest)(nil), // 41: daemon.SetTailscaleExitNodeRequest
|
||||||
(*emptypb.Empty)(nil), // 42: google.protobuf.Empty
|
(*Log_Message)(nil), // 42: daemon.Log.Message
|
||||||
|
(*emptypb.Empty)(nil), // 43: 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
|
||||||
41, // 1: daemon.Log.messages:type_name -> daemon.Log.Message
|
42, // 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
|
||||||
@@ -3106,69 +3181,72 @@ var file_daemon_started_service_proto_depIdxs = []int32{
|
|||||||
36, // 12: daemon.TailscaleStatusUpdate.endpoints:type_name -> daemon.TailscaleEndpointStatus
|
36, // 12: daemon.TailscaleStatusUpdate.endpoints:type_name -> daemon.TailscaleEndpointStatus
|
||||||
38, // 13: daemon.TailscaleEndpointStatus.self:type_name -> daemon.TailscalePeer
|
38, // 13: daemon.TailscaleEndpointStatus.self:type_name -> daemon.TailscalePeer
|
||||||
37, // 14: daemon.TailscaleEndpointStatus.userGroups:type_name -> daemon.TailscaleUserGroup
|
37, // 14: daemon.TailscaleEndpointStatus.userGroups:type_name -> daemon.TailscaleUserGroup
|
||||||
38, // 15: daemon.TailscaleUserGroup.peers:type_name -> daemon.TailscalePeer
|
38, // 15: daemon.TailscaleEndpointStatus.exitNode:type_name -> daemon.TailscalePeer
|
||||||
0, // 16: daemon.Log.Message.level:type_name -> daemon.LogLevel
|
38, // 16: daemon.TailscaleUserGroup.peers:type_name -> daemon.TailscalePeer
|
||||||
42, // 17: daemon.StartedService.StopService:input_type -> google.protobuf.Empty
|
0, // 17: daemon.Log.Message.level:type_name -> daemon.LogLevel
|
||||||
42, // 18: daemon.StartedService.ReloadService:input_type -> google.protobuf.Empty
|
43, // 18: daemon.StartedService.StopService:input_type -> google.protobuf.Empty
|
||||||
42, // 19: daemon.StartedService.SubscribeServiceStatus:input_type -> google.protobuf.Empty
|
43, // 19: daemon.StartedService.ReloadService:input_type -> google.protobuf.Empty
|
||||||
42, // 20: daemon.StartedService.SubscribeLog:input_type -> google.protobuf.Empty
|
43, // 20: daemon.StartedService.SubscribeServiceStatus:input_type -> google.protobuf.Empty
|
||||||
42, // 21: daemon.StartedService.GetDefaultLogLevel:input_type -> google.protobuf.Empty
|
43, // 21: daemon.StartedService.SubscribeLog:input_type -> google.protobuf.Empty
|
||||||
42, // 22: daemon.StartedService.ClearLogs:input_type -> google.protobuf.Empty
|
43, // 22: daemon.StartedService.GetDefaultLogLevel:input_type -> google.protobuf.Empty
|
||||||
6, // 23: daemon.StartedService.SubscribeStatus:input_type -> daemon.SubscribeStatusRequest
|
43, // 23: daemon.StartedService.ClearLogs:input_type -> google.protobuf.Empty
|
||||||
42, // 24: daemon.StartedService.SubscribeGroups:input_type -> google.protobuf.Empty
|
6, // 24: daemon.StartedService.SubscribeStatus:input_type -> daemon.SubscribeStatusRequest
|
||||||
42, // 25: daemon.StartedService.GetClashModeStatus:input_type -> google.protobuf.Empty
|
43, // 25: daemon.StartedService.SubscribeGroups:input_type -> google.protobuf.Empty
|
||||||
42, // 26: daemon.StartedService.SubscribeClashMode:input_type -> google.protobuf.Empty
|
43, // 26: daemon.StartedService.GetClashModeStatus:input_type -> google.protobuf.Empty
|
||||||
16, // 27: daemon.StartedService.SetClashMode:input_type -> daemon.ClashMode
|
43, // 27: daemon.StartedService.SubscribeClashMode:input_type -> google.protobuf.Empty
|
||||||
13, // 28: daemon.StartedService.URLTest:input_type -> daemon.URLTestRequest
|
16, // 28: daemon.StartedService.SetClashMode:input_type -> daemon.ClashMode
|
||||||
14, // 29: daemon.StartedService.SelectOutbound:input_type -> daemon.SelectOutboundRequest
|
13, // 29: daemon.StartedService.URLTest:input_type -> daemon.URLTestRequest
|
||||||
15, // 30: daemon.StartedService.SetGroupExpand:input_type -> daemon.SetGroupExpandRequest
|
14, // 30: daemon.StartedService.SelectOutbound:input_type -> daemon.SelectOutboundRequest
|
||||||
42, // 31: daemon.StartedService.GetSystemProxyStatus:input_type -> google.protobuf.Empty
|
15, // 31: daemon.StartedService.SetGroupExpand:input_type -> daemon.SetGroupExpandRequest
|
||||||
19, // 32: daemon.StartedService.SetSystemProxyEnabled:input_type -> daemon.SetSystemProxyEnabledRequest
|
43, // 32: daemon.StartedService.GetSystemProxyStatus:input_type -> google.protobuf.Empty
|
||||||
20, // 33: daemon.StartedService.TriggerDebugCrash:input_type -> daemon.DebugCrashRequest
|
19, // 33: daemon.StartedService.SetSystemProxyEnabled:input_type -> daemon.SetSystemProxyEnabledRequest
|
||||||
42, // 34: daemon.StartedService.TriggerOOMReport:input_type -> google.protobuf.Empty
|
20, // 34: daemon.StartedService.TriggerDebugCrash:input_type -> daemon.DebugCrashRequest
|
||||||
21, // 35: daemon.StartedService.SubscribeConnections:input_type -> daemon.SubscribeConnectionsRequest
|
43, // 35: daemon.StartedService.TriggerOOMReport:input_type -> google.protobuf.Empty
|
||||||
26, // 36: daemon.StartedService.CloseConnection:input_type -> daemon.CloseConnectionRequest
|
21, // 36: daemon.StartedService.SubscribeConnections:input_type -> daemon.SubscribeConnectionsRequest
|
||||||
42, // 37: daemon.StartedService.CloseAllConnections:input_type -> google.protobuf.Empty
|
26, // 37: daemon.StartedService.CloseConnection:input_type -> daemon.CloseConnectionRequest
|
||||||
42, // 38: daemon.StartedService.GetDeprecatedWarnings:input_type -> google.protobuf.Empty
|
43, // 38: daemon.StartedService.CloseAllConnections:input_type -> google.protobuf.Empty
|
||||||
42, // 39: daemon.StartedService.GetStartedAt:input_type -> google.protobuf.Empty
|
43, // 39: daemon.StartedService.GetDeprecatedWarnings:input_type -> google.protobuf.Empty
|
||||||
42, // 40: daemon.StartedService.SubscribeOutbounds:input_type -> google.protobuf.Empty
|
43, // 40: daemon.StartedService.GetStartedAt:input_type -> google.protobuf.Empty
|
||||||
31, // 41: daemon.StartedService.StartNetworkQualityTest:input_type -> daemon.NetworkQualityTestRequest
|
43, // 41: daemon.StartedService.SubscribeOutbounds:input_type -> google.protobuf.Empty
|
||||||
33, // 42: daemon.StartedService.StartSTUNTest:input_type -> daemon.STUNTestRequest
|
31, // 42: daemon.StartedService.StartNetworkQualityTest:input_type -> daemon.NetworkQualityTestRequest
|
||||||
42, // 43: daemon.StartedService.SubscribeTailscaleStatus:input_type -> google.protobuf.Empty
|
33, // 43: daemon.StartedService.StartSTUNTest:input_type -> daemon.STUNTestRequest
|
||||||
39, // 44: daemon.StartedService.StartTailscalePing:input_type -> daemon.TailscalePingRequest
|
43, // 44: daemon.StartedService.SubscribeTailscaleStatus:input_type -> google.protobuf.Empty
|
||||||
42, // 45: daemon.StartedService.StopService:output_type -> google.protobuf.Empty
|
39, // 45: daemon.StartedService.StartTailscalePing:input_type -> daemon.TailscalePingRequest
|
||||||
42, // 46: daemon.StartedService.ReloadService:output_type -> google.protobuf.Empty
|
41, // 46: daemon.StartedService.SetTailscaleExitNode:input_type -> daemon.SetTailscaleExitNodeRequest
|
||||||
4, // 47: daemon.StartedService.SubscribeServiceStatus:output_type -> daemon.ServiceStatus
|
43, // 47: daemon.StartedService.StopService:output_type -> google.protobuf.Empty
|
||||||
7, // 48: daemon.StartedService.SubscribeLog:output_type -> daemon.Log
|
43, // 48: daemon.StartedService.ReloadService:output_type -> google.protobuf.Empty
|
||||||
8, // 49: daemon.StartedService.GetDefaultLogLevel:output_type -> daemon.DefaultLogLevel
|
4, // 49: daemon.StartedService.SubscribeServiceStatus:output_type -> daemon.ServiceStatus
|
||||||
42, // 50: daemon.StartedService.ClearLogs:output_type -> google.protobuf.Empty
|
7, // 50: daemon.StartedService.SubscribeLog:output_type -> daemon.Log
|
||||||
9, // 51: daemon.StartedService.SubscribeStatus:output_type -> daemon.Status
|
8, // 51: daemon.StartedService.GetDefaultLogLevel:output_type -> daemon.DefaultLogLevel
|
||||||
10, // 52: daemon.StartedService.SubscribeGroups:output_type -> daemon.Groups
|
43, // 52: daemon.StartedService.ClearLogs:output_type -> google.protobuf.Empty
|
||||||
17, // 53: daemon.StartedService.GetClashModeStatus:output_type -> daemon.ClashModeStatus
|
9, // 53: daemon.StartedService.SubscribeStatus:output_type -> daemon.Status
|
||||||
16, // 54: daemon.StartedService.SubscribeClashMode:output_type -> daemon.ClashMode
|
10, // 54: daemon.StartedService.SubscribeGroups:output_type -> daemon.Groups
|
||||||
42, // 55: daemon.StartedService.SetClashMode:output_type -> google.protobuf.Empty
|
17, // 55: daemon.StartedService.GetClashModeStatus:output_type -> daemon.ClashModeStatus
|
||||||
42, // 56: daemon.StartedService.URLTest:output_type -> google.protobuf.Empty
|
16, // 56: daemon.StartedService.SubscribeClashMode:output_type -> daemon.ClashMode
|
||||||
42, // 57: daemon.StartedService.SelectOutbound:output_type -> google.protobuf.Empty
|
43, // 57: daemon.StartedService.SetClashMode:output_type -> google.protobuf.Empty
|
||||||
42, // 58: daemon.StartedService.SetGroupExpand:output_type -> google.protobuf.Empty
|
43, // 58: daemon.StartedService.URLTest:output_type -> google.protobuf.Empty
|
||||||
18, // 59: daemon.StartedService.GetSystemProxyStatus:output_type -> daemon.SystemProxyStatus
|
43, // 59: daemon.StartedService.SelectOutbound:output_type -> google.protobuf.Empty
|
||||||
42, // 60: daemon.StartedService.SetSystemProxyEnabled:output_type -> google.protobuf.Empty
|
43, // 60: daemon.StartedService.SetGroupExpand:output_type -> google.protobuf.Empty
|
||||||
42, // 61: daemon.StartedService.TriggerDebugCrash:output_type -> google.protobuf.Empty
|
18, // 61: daemon.StartedService.GetSystemProxyStatus:output_type -> daemon.SystemProxyStatus
|
||||||
42, // 62: daemon.StartedService.TriggerOOMReport:output_type -> google.protobuf.Empty
|
43, // 62: daemon.StartedService.SetSystemProxyEnabled:output_type -> google.protobuf.Empty
|
||||||
23, // 63: daemon.StartedService.SubscribeConnections:output_type -> daemon.ConnectionEvents
|
43, // 63: daemon.StartedService.TriggerDebugCrash:output_type -> google.protobuf.Empty
|
||||||
42, // 64: daemon.StartedService.CloseConnection:output_type -> google.protobuf.Empty
|
43, // 64: daemon.StartedService.TriggerOOMReport:output_type -> google.protobuf.Empty
|
||||||
42, // 65: daemon.StartedService.CloseAllConnections:output_type -> google.protobuf.Empty
|
23, // 65: daemon.StartedService.SubscribeConnections:output_type -> daemon.ConnectionEvents
|
||||||
27, // 66: daemon.StartedService.GetDeprecatedWarnings:output_type -> daemon.DeprecatedWarnings
|
43, // 66: daemon.StartedService.CloseConnection:output_type -> google.protobuf.Empty
|
||||||
29, // 67: daemon.StartedService.GetStartedAt:output_type -> daemon.StartedAt
|
43, // 67: daemon.StartedService.CloseAllConnections:output_type -> google.protobuf.Empty
|
||||||
30, // 68: daemon.StartedService.SubscribeOutbounds:output_type -> daemon.OutboundList
|
27, // 68: daemon.StartedService.GetDeprecatedWarnings:output_type -> daemon.DeprecatedWarnings
|
||||||
32, // 69: daemon.StartedService.StartNetworkQualityTest:output_type -> daemon.NetworkQualityTestProgress
|
29, // 69: daemon.StartedService.GetStartedAt:output_type -> daemon.StartedAt
|
||||||
34, // 70: daemon.StartedService.StartSTUNTest:output_type -> daemon.STUNTestProgress
|
30, // 70: daemon.StartedService.SubscribeOutbounds:output_type -> daemon.OutboundList
|
||||||
35, // 71: daemon.StartedService.SubscribeTailscaleStatus:output_type -> daemon.TailscaleStatusUpdate
|
32, // 71: daemon.StartedService.StartNetworkQualityTest:output_type -> daemon.NetworkQualityTestProgress
|
||||||
40, // 72: daemon.StartedService.StartTailscalePing:output_type -> daemon.TailscalePingResponse
|
34, // 72: daemon.StartedService.StartSTUNTest:output_type -> daemon.STUNTestProgress
|
||||||
45, // [45:73] is the sub-list for method output_type
|
35, // 73: daemon.StartedService.SubscribeTailscaleStatus:output_type -> daemon.TailscaleStatusUpdate
|
||||||
17, // [17:45] is the sub-list for method input_type
|
40, // 74: daemon.StartedService.StartTailscalePing:output_type -> daemon.TailscalePingResponse
|
||||||
17, // [17:17] is the sub-list for extension type_name
|
43, // 75: daemon.StartedService.SetTailscaleExitNode:output_type -> google.protobuf.Empty
|
||||||
17, // [17:17] is the sub-list for extension extendee
|
47, // [47:76] is the sub-list for method output_type
|
||||||
0, // [0:17] is the sub-list for field type_name
|
18, // [18:47] is the sub-list for method input_type
|
||||||
|
18, // [18:18] is the sub-list for extension type_name
|
||||||
|
18, // [18:18] is the sub-list for extension extendee
|
||||||
|
0, // [0:18] is the sub-list for field type_name
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { file_daemon_started_service_proto_init() }
|
func init() { file_daemon_started_service_proto_init() }
|
||||||
@@ -3182,7 +3260,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: 38,
|
NumMessages: 39,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 1,
|
NumServices: 1,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ service StartedService {
|
|||||||
rpc StartSTUNTest(STUNTestRequest) returns (stream STUNTestProgress) {}
|
rpc StartSTUNTest(STUNTestRequest) returns (stream STUNTestProgress) {}
|
||||||
rpc SubscribeTailscaleStatus(google.protobuf.Empty) returns (stream TailscaleStatusUpdate) {}
|
rpc SubscribeTailscaleStatus(google.protobuf.Empty) returns (stream TailscaleStatusUpdate) {}
|
||||||
rpc StartTailscalePing(TailscalePingRequest) returns (stream TailscalePingResponse) {}
|
rpc StartTailscalePing(TailscalePingRequest) returns (stream TailscalePingResponse) {}
|
||||||
|
rpc SetTailscaleExitNode(SetTailscaleExitNodeRequest) returns (google.protobuf.Empty) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
message ServiceStatus {
|
message ServiceStatus {
|
||||||
@@ -292,6 +293,7 @@ message TailscaleEndpointStatus {
|
|||||||
string magicDNSSuffix = 5;
|
string magicDNSSuffix = 5;
|
||||||
TailscalePeer self = 6;
|
TailscalePeer self = 6;
|
||||||
repeated TailscaleUserGroup userGroups = 7;
|
repeated TailscaleUserGroup userGroups = 7;
|
||||||
|
TailscalePeer exitNode = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
message TailscaleUserGroup {
|
message TailscaleUserGroup {
|
||||||
@@ -314,6 +316,7 @@ message TailscalePeer {
|
|||||||
int64 rxBytes = 9;
|
int64 rxBytes = 9;
|
||||||
int64 txBytes = 10;
|
int64 txBytes = 10;
|
||||||
int64 keyExpiry = 11;
|
int64 keyExpiry = 11;
|
||||||
|
string stableID = 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
message TailscalePingRequest {
|
message TailscalePingRequest {
|
||||||
@@ -329,3 +332,8 @@ message TailscalePingResponse {
|
|||||||
string derpRegionCode = 5;
|
string derpRegionCode = 5;
|
||||||
string error = 6;
|
string error = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message SetTailscaleExitNodeRequest {
|
||||||
|
string endpointTag = 1;
|
||||||
|
string stableID = 2;
|
||||||
|
}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ const (
|
|||||||
StartedService_StartSTUNTest_FullMethodName = "/daemon.StartedService/StartSTUNTest"
|
StartedService_StartSTUNTest_FullMethodName = "/daemon.StartedService/StartSTUNTest"
|
||||||
StartedService_SubscribeTailscaleStatus_FullMethodName = "/daemon.StartedService/SubscribeTailscaleStatus"
|
StartedService_SubscribeTailscaleStatus_FullMethodName = "/daemon.StartedService/SubscribeTailscaleStatus"
|
||||||
StartedService_StartTailscalePing_FullMethodName = "/daemon.StartedService/StartTailscalePing"
|
StartedService_StartTailscalePing_FullMethodName = "/daemon.StartedService/StartTailscalePing"
|
||||||
|
StartedService_SetTailscaleExitNode_FullMethodName = "/daemon.StartedService/SetTailscaleExitNode"
|
||||||
)
|
)
|
||||||
|
|
||||||
// StartedServiceClient is the client API for StartedService service.
|
// StartedServiceClient is the client API for StartedService service.
|
||||||
@@ -77,6 +78,7 @@ type StartedServiceClient interface {
|
|||||||
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)
|
SubscribeTailscaleStatus(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (grpc.ServerStreamingClient[TailscaleStatusUpdate], error)
|
||||||
StartTailscalePing(ctx context.Context, in *TailscalePingRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[TailscalePingResponse], error)
|
StartTailscalePing(ctx context.Context, in *TailscalePingRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[TailscalePingResponse], error)
|
||||||
|
SetTailscaleExitNode(ctx context.Context, in *SetTailscaleExitNodeRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type startedServiceClient struct {
|
type startedServiceClient struct {
|
||||||
@@ -466,6 +468,16 @@ func (c *startedServiceClient) StartTailscalePing(ctx context.Context, in *Tails
|
|||||||
// 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_StartTailscalePingClient = grpc.ServerStreamingClient[TailscalePingResponse]
|
type StartedService_StartTailscalePingClient = grpc.ServerStreamingClient[TailscalePingResponse]
|
||||||
|
|
||||||
|
func (c *startedServiceClient) SetTailscaleExitNode(ctx context.Context, in *SetTailscaleExitNodeRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(emptypb.Empty)
|
||||||
|
err := c.cc.Invoke(ctx, StartedService_SetTailscaleExitNode_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
// 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.
|
||||||
@@ -498,6 +510,7 @@ type StartedServiceServer interface {
|
|||||||
StartSTUNTest(*STUNTestRequest, grpc.ServerStreamingServer[STUNTestProgress]) error
|
StartSTUNTest(*STUNTestRequest, grpc.ServerStreamingServer[STUNTestProgress]) error
|
||||||
SubscribeTailscaleStatus(*emptypb.Empty, grpc.ServerStreamingServer[TailscaleStatusUpdate]) error
|
SubscribeTailscaleStatus(*emptypb.Empty, grpc.ServerStreamingServer[TailscaleStatusUpdate]) error
|
||||||
StartTailscalePing(*TailscalePingRequest, grpc.ServerStreamingServer[TailscalePingResponse]) error
|
StartTailscalePing(*TailscalePingRequest, grpc.ServerStreamingServer[TailscalePingResponse]) error
|
||||||
|
SetTailscaleExitNode(context.Context, *SetTailscaleExitNodeRequest) (*emptypb.Empty, error)
|
||||||
mustEmbedUnimplementedStartedServiceServer()
|
mustEmbedUnimplementedStartedServiceServer()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -619,6 +632,10 @@ func (UnimplementedStartedServiceServer) SubscribeTailscaleStatus(*emptypb.Empty
|
|||||||
func (UnimplementedStartedServiceServer) StartTailscalePing(*TailscalePingRequest, grpc.ServerStreamingServer[TailscalePingResponse]) error {
|
func (UnimplementedStartedServiceServer) StartTailscalePing(*TailscalePingRequest, grpc.ServerStreamingServer[TailscalePingResponse]) error {
|
||||||
return status.Error(codes.Unimplemented, "method StartTailscalePing not implemented")
|
return status.Error(codes.Unimplemented, "method StartTailscalePing not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (UnimplementedStartedServiceServer) SetTailscaleExitNode(context.Context, *SetTailscaleExitNodeRequest) (*emptypb.Empty, error) {
|
||||||
|
return nil, status.Error(codes.Unimplemented, "method SetTailscaleExitNode not implemented")
|
||||||
|
}
|
||||||
func (UnimplementedStartedServiceServer) mustEmbedUnimplementedStartedServiceServer() {}
|
func (UnimplementedStartedServiceServer) mustEmbedUnimplementedStartedServiceServer() {}
|
||||||
func (UnimplementedStartedServiceServer) testEmbeddedByValue() {}
|
func (UnimplementedStartedServiceServer) testEmbeddedByValue() {}
|
||||||
|
|
||||||
@@ -1067,6 +1084,24 @@ func _StartedService_StartTailscalePing_Handler(srv interface{}, stream grpc.Ser
|
|||||||
// 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_StartTailscalePingServer = grpc.ServerStreamingServer[TailscalePingResponse]
|
type StartedService_StartTailscalePingServer = grpc.ServerStreamingServer[TailscalePingResponse]
|
||||||
|
|
||||||
|
func _StartedService_SetTailscaleExitNode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(SetTailscaleExitNodeRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(StartedServiceServer).SetTailscaleExitNode(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: StartedService_SetTailscaleExitNode_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(StartedServiceServer).SetTailscaleExitNode(ctx, req.(*SetTailscaleExitNodeRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
// 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)
|
||||||
@@ -1142,6 +1177,10 @@ var StartedService_ServiceDesc = grpc.ServiceDesc{
|
|||||||
MethodName: "GetStartedAt",
|
MethodName: "GetStartedAt",
|
||||||
Handler: _StartedService_GetStartedAt_Handler,
|
Handler: _StartedService_GetStartedAt_Handler,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
MethodName: "SetTailscaleExitNode",
|
||||||
|
Handler: _StartedService_SetTailscaleExitNode_Handler,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Streams: []grpc.StreamDesc{
|
Streams: []grpc.StreamDesc{
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -780,6 +780,19 @@ func (c *CommandClient) SubscribeTailscaleStatus(handler TailscaleStatusHandler)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *CommandClient) SetTailscaleExitNode(endpointTag string, stableID string) error {
|
||||||
|
_, err := callWithResult(c, func(client daemon.StartedServiceClient) (*emptypb.Empty, error) {
|
||||||
|
return client.SetTailscaleExitNode(context.Background(), &daemon.SetTailscaleExitNodeRequest{
|
||||||
|
EndpointTag: endpointTag,
|
||||||
|
StableID: stableID,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return E.Cause(err, "set tailscale exit node")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *CommandClient) StartTailscalePing(endpointTag string, peerIP string, handler TailscalePingHandler) error {
|
func (c *CommandClient) StartTailscalePing(endpointTag string, peerIP string, handler TailscalePingHandler) error {
|
||||||
client, err := c.getClientForCall()
|
client, err := c.getClientForCall()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ type TailscaleEndpointStatus struct {
|
|||||||
NetworkName string
|
NetworkName string
|
||||||
MagicDNSSuffix string
|
MagicDNSSuffix string
|
||||||
Self *TailscalePeer
|
Self *TailscalePeer
|
||||||
|
ExitNode *TailscalePeer
|
||||||
userGroups []*TailscaleUserGroup
|
userGroups []*TailscaleUserGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,6 +53,7 @@ type TailscalePeerIterator interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type TailscalePeer struct {
|
type TailscalePeer struct {
|
||||||
|
StableID string
|
||||||
HostName string
|
HostName string
|
||||||
DNSName string
|
DNSName string
|
||||||
OS string
|
OS string
|
||||||
@@ -98,6 +100,9 @@ func tailscaleEndpointStatusFromGRPC(status *daemon.TailscaleEndpointStatus) *Ta
|
|||||||
if status.Self != nil {
|
if status.Self != nil {
|
||||||
result.Self = tailscalePeerFromGRPC(status.Self)
|
result.Self = tailscalePeerFromGRPC(status.Self)
|
||||||
}
|
}
|
||||||
|
if status.ExitNode != nil {
|
||||||
|
result.ExitNode = tailscalePeerFromGRPC(status.ExitNode)
|
||||||
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,6 +122,7 @@ func tailscaleUserGroupFromGRPC(group *daemon.TailscaleUserGroup) *TailscaleUser
|
|||||||
|
|
||||||
func tailscalePeerFromGRPC(peer *daemon.TailscalePeer) *TailscalePeer {
|
func tailscalePeerFromGRPC(peer *daemon.TailscalePeer) *TailscalePeer {
|
||||||
return &TailscalePeer{
|
return &TailscalePeer{
|
||||||
|
StableID: peer.StableID,
|
||||||
HostName: peer.HostName,
|
HostName: peer.HostName,
|
||||||
DNSName: peer.DnsName,
|
DNSName: peer.DnsName,
|
||||||
OS: peer.Os,
|
OS: peer.Os,
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ import (
|
|||||||
"github.com/sagernet/tailscale/net/netns"
|
"github.com/sagernet/tailscale/net/netns"
|
||||||
"github.com/sagernet/tailscale/net/tsaddr"
|
"github.com/sagernet/tailscale/net/tsaddr"
|
||||||
tsTUN "github.com/sagernet/tailscale/net/tstun"
|
tsTUN "github.com/sagernet/tailscale/net/tstun"
|
||||||
|
"github.com/sagernet/tailscale/tailcfg"
|
||||||
"github.com/sagernet/tailscale/tsnet"
|
"github.com/sagernet/tailscale/tsnet"
|
||||||
"github.com/sagernet/tailscale/types/ipproto"
|
"github.com/sagernet/tailscale/types/ipproto"
|
||||||
"github.com/sagernet/tailscale/types/nettype"
|
"github.com/sagernet/tailscale/types/nettype"
|
||||||
@@ -487,6 +488,49 @@ func (t *Endpoint) watchState() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Endpoint) SetTailscaleExitNode(ctx context.Context, stableID string) error {
|
||||||
|
if !t.started.Load() {
|
||||||
|
return E.New("Tailscale is not ready yet")
|
||||||
|
}
|
||||||
|
if t.advertiseExitNode && stableID != "" {
|
||||||
|
return E.New("cannot advertise an exit node and use an exit node at the same time")
|
||||||
|
}
|
||||||
|
perfs := &ipn.MaskedPrefs{
|
||||||
|
Prefs: ipn.Prefs{
|
||||||
|
ExitNodeID: tailcfg.StableNodeID(stableID),
|
||||||
|
ExitNodeAllowLANAccess: t.exitNodeAllowLANAccess,
|
||||||
|
},
|
||||||
|
ExitNodeIDSet: true,
|
||||||
|
ExitNodeIPSet: true,
|
||||||
|
ExitNodeAllowLANAccessSet: true,
|
||||||
|
}
|
||||||
|
if stableID != "" {
|
||||||
|
status, err := common.Must1(t.server.LocalClient()).Status(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return E.Cause(err, "get tailscale status")
|
||||||
|
}
|
||||||
|
found := false
|
||||||
|
for _, peer := range status.Peer {
|
||||||
|
if peer.ID != tailcfg.StableNodeID(stableID) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !peer.ExitNodeOption {
|
||||||
|
return E.New("peer does not offer exit node: ", stableID)
|
||||||
|
}
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
return E.New("peer not found: ", stableID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, err := t.server.ExportLocalBackend().EditPrefs(perfs)
|
||||||
|
if err != nil {
|
||||||
|
return E.Cause(err, "update prefs")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (t *Endpoint) Close() error {
|
func (t *Endpoint) Close() error {
|
||||||
var err error
|
var err error
|
||||||
t.started.Store(false)
|
t.started.Store(false)
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ func (t *Endpoint) SubscribeTailscaleStatus(ctx context.Context, fn func(*adapte
|
|||||||
return false
|
return false
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
if roNotify.State != nil || roNotify.NetMap != nil || roNotify.BrowseToURL != nil {
|
if roNotify.State != nil || roNotify.NetMap != nil || roNotify.BrowseToURL != nil || roNotify.Prefs != nil {
|
||||||
sendStatus()
|
sendStatus()
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@@ -76,6 +76,27 @@ func convertTailscaleStatus(status *ipnstate.Status) *adapter.TailscaleEndpointS
|
|||||||
return 0
|
return 0
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
if status.ExitNodeStatus != nil {
|
||||||
|
for _, peerKey := range status.Peers() {
|
||||||
|
peer := status.Peer[peerKey]
|
||||||
|
if peer.ID == status.ExitNodeStatus.ID {
|
||||||
|
result.ExitNode = convertTailscalePeer(peer)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if result.ExitNode == nil {
|
||||||
|
ips := make([]string, 0, len(status.ExitNodeStatus.TailscaleIPs))
|
||||||
|
for _, prefix := range status.ExitNodeStatus.TailscaleIPs {
|
||||||
|
ips = append(ips, prefix.Addr().String())
|
||||||
|
}
|
||||||
|
result.ExitNode = &adapter.TailscalePeer{
|
||||||
|
StableID: string(status.ExitNodeStatus.ID),
|
||||||
|
TailscaleIPs: ips,
|
||||||
|
Online: status.ExitNodeStatus.Online,
|
||||||
|
ExitNode: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,6 +110,7 @@ func convertTailscalePeer(peer *ipnstate.PeerStatus) *adapter.TailscalePeer {
|
|||||||
keyExpiry = peer.KeyExpiry.Unix()
|
keyExpiry = peer.KeyExpiry.Unix()
|
||||||
}
|
}
|
||||||
return &adapter.TailscalePeer{
|
return &adapter.TailscalePeer{
|
||||||
|
StableID: string(peer.ID),
|
||||||
HostName: peer.HostName,
|
HostName: peer.HostName,
|
||||||
DNSName: peer.DNSName,
|
DNSName: peer.DNSName,
|
||||||
OS: peer.OS,
|
OS: peer.OS,
|
||||||
|
|||||||
Reference in New Issue
Block a user