tailscale: Add runtime exit node API
This commit is contained in:
@@ -53,6 +53,7 @@ import (
|
||||
"github.com/sagernet/tailscale/net/netns"
|
||||
"github.com/sagernet/tailscale/net/tsaddr"
|
||||
tsTUN "github.com/sagernet/tailscale/net/tstun"
|
||||
"github.com/sagernet/tailscale/tailcfg"
|
||||
"github.com/sagernet/tailscale/tsnet"
|
||||
"github.com/sagernet/tailscale/types/ipproto"
|
||||
"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 {
|
||||
var err error
|
||||
t.started.Store(false)
|
||||
|
||||
@@ -26,7 +26,7 @@ func (t *Endpoint) SubscribeTailscaleStatus(ctx context.Context, fn func(*adapte
|
||||
return false
|
||||
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()
|
||||
}
|
||||
return true
|
||||
@@ -76,6 +76,27 @@ func convertTailscaleStatus(status *ipnstate.Status) *adapter.TailscaleEndpointS
|
||||
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
|
||||
}
|
||||
|
||||
@@ -89,6 +110,7 @@ func convertTailscalePeer(peer *ipnstate.PeerStatus) *adapter.TailscalePeer {
|
||||
keyExpiry = peer.KeyExpiry.Unix()
|
||||
}
|
||||
return &adapter.TailscalePeer{
|
||||
StableID: string(peer.ID),
|
||||
HostName: peer.HostName,
|
||||
DNSName: peer.DNSName,
|
||||
OS: peer.OS,
|
||||
|
||||
Reference in New Issue
Block a user