mirror of
https://github.com/tailscale/tailscale.git
synced 2025-12-02 18:11:59 +00:00
add debug cmd for routeInfo
This commit is contained in:
@@ -98,6 +98,8 @@ func (e *AppConnector) UpdateDomainsAndRoutes(domains []string, routes []netip.P
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e *AppConnector) RouteInfo() *routeinfo.RouteInfo {
|
func (e *AppConnector) RouteInfo() *routeinfo.RouteInfo {
|
||||||
|
// e.mu.Lock()
|
||||||
|
// defer e.mu.Unlock()
|
||||||
if e.routeInfo == nil {
|
if e.routeInfo == nil {
|
||||||
ret, err := e.routeAdvertiser.ReadRouteInfo()
|
ret, err := e.routeAdvertiser.ReadRouteInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -113,7 +115,7 @@ func (e *AppConnector) RouteInfo() *routeinfo.RouteInfo {
|
|||||||
|
|
||||||
// RecreateRouteInfoFromStore searches from presist store for existing routeInfo for current profile,
|
// RecreateRouteInfoFromStore searches from presist store for existing routeInfo for current profile,
|
||||||
// then update local routes of routeInfo in store as the current advertised routes.
|
// then update local routes of routeInfo in store as the current advertised routes.
|
||||||
func (e *AppConnector) RecreateRouteInfoFromStore(localRoutes []netip.Prefix) {
|
func (e *AppConnector) RecreateRouteInfoFromStore() {
|
||||||
e.queue.Add(func() {
|
e.queue.Add(func() {
|
||||||
e.mu.Lock()
|
e.mu.Lock()
|
||||||
defer e.mu.Unlock()
|
defer e.mu.Unlock()
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ func NewRouteInfo() *RouteInfo {
|
|||||||
return &RouteInfo{
|
return &RouteInfo{
|
||||||
Control: []netip.Prefix{},
|
Control: []netip.Prefix{},
|
||||||
Discovered: discovered,
|
Discovered: discovered,
|
||||||
|
Wildcards: []string{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"go4.org/mem"
|
"go4.org/mem"
|
||||||
|
"tailscale.com/appc/routeinfo"
|
||||||
"tailscale.com/client/tailscale/apitype"
|
"tailscale.com/client/tailscale/apitype"
|
||||||
"tailscale.com/drive"
|
"tailscale.com/drive"
|
||||||
"tailscale.com/envknob"
|
"tailscale.com/envknob"
|
||||||
@@ -722,6 +723,18 @@ func (lc *LocalClient) GetPrefs(ctx context.Context) (*ipn.Prefs, error) {
|
|||||||
return &p, nil
|
return &p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (lc *LocalClient) GetRouteInfo(ctx context.Context) (*routeinfo.RouteInfo, error) {
|
||||||
|
body, err := lc.get200(ctx, "/localapi/v0/routeInfo")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var p routeinfo.RouteInfo
|
||||||
|
if err := json.Unmarshal(body, &p); err != nil {
|
||||||
|
return nil, fmt.Errorf("invalid prefs JSON: %w", err)
|
||||||
|
}
|
||||||
|
return &p, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (lc *LocalClient) EditPrefs(ctx context.Context, mp *ipn.MaskedPrefs) (*ipn.Prefs, error) {
|
func (lc *LocalClient) EditPrefs(ctx context.Context, mp *ipn.MaskedPrefs) (*ipn.Prefs, error) {
|
||||||
body, err := lc.send(ctx, "PATCH", "/localapi/v0/prefs", http.StatusOK, jsonBody(mp))
|
body, err := lc.send(ctx, "PATCH", "/localapi/v0/prefs", http.StatusOK, jsonBody(mp))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -316,6 +316,12 @@ var debugCmd = &ffcli.Command{
|
|||||||
return fs
|
return fs
|
||||||
})(),
|
})(),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "appc-routes",
|
||||||
|
ShortUsage: "tailscale debug appc-routes",
|
||||||
|
Exec: runDebugAppc,
|
||||||
|
ShortHelp: "Prints the routes the node is advertising if it is running as an appConnector. ",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1115,3 +1121,14 @@ func runDebugDialTypes(ctx context.Context, args []string) error {
|
|||||||
fmt.Printf("%s", body)
|
fmt.Printf("%s", body)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func runDebugAppc(ctx context.Context, args []string) error {
|
||||||
|
prefs, err := localClient.GetRouteInfo(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
j, _ := json.MarshalIndent(prefs, "", "\t")
|
||||||
|
outln(string(j))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -3573,7 +3573,7 @@ func (b *LocalBackend) reconfigAppConnectorLocked(nm *netmap.NetworkMap, prefs i
|
|||||||
if b.appConnector == nil || shouldAppCStoreRoutesHasChanged {
|
if b.appConnector == nil || shouldAppCStoreRoutesHasChanged {
|
||||||
b.appConnector = appc.NewAppConnector(b.logf, b, shouldAppCStoreRoutes)
|
b.appConnector = appc.NewAppConnector(b.logf, b, shouldAppCStoreRoutes)
|
||||||
if shouldAppCStoreRoutes {
|
if shouldAppCStoreRoutes {
|
||||||
b.appConnector.RecreateRouteInfoFromStore(prefs.AsStruct().AdvertiseRoutes)
|
b.appConnector.RecreateRouteInfoFromStore()
|
||||||
} else if shouldAppCStoreRoutesHasChanged && !shouldAppCStoreRoutes {
|
} else if shouldAppCStoreRoutesHasChanged && !shouldAppCStoreRoutes {
|
||||||
b.appConnector.UpdateRouteInfo(nil)
|
b.appConnector.UpdateRouteInfo(nil)
|
||||||
}
|
}
|
||||||
@@ -4179,7 +4179,9 @@ func (b *LocalBackend) routerConfig(cfg *wgcfg.Config, prefs ipn.PrefsView, oneC
|
|||||||
netfilterKind = prefs.NetfilterKind()
|
netfilterKind = prefs.NetfilterKind()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
b.mu.Lock()
|
||||||
toAdvertise := b.appConnector.RouteInfo().Routes(true, true)
|
toAdvertise := b.appConnector.RouteInfo().Routes(true, true)
|
||||||
|
b.mu.Unlock()
|
||||||
toAdvertise = append(toAdvertise, prefs.AdvertiseRoutes().AsSlice()...)
|
toAdvertise = append(toAdvertise, prefs.AdvertiseRoutes().AsSlice()...)
|
||||||
rs := &router.Config{
|
rs := &router.Config{
|
||||||
LocalAddrs: unmapIPPrefixes(cfg.Addresses),
|
LocalAddrs: unmapIPPrefixes(cfg.Addresses),
|
||||||
@@ -4270,7 +4272,7 @@ func (b *LocalBackend) applyPrefsToHostinfoLocked(hi *tailcfg.Hostinfo, prefs ip
|
|||||||
|
|
||||||
var routableIPs []netip.Prefix
|
var routableIPs []netip.Prefix
|
||||||
if b.appConnector != nil {
|
if b.appConnector != nil {
|
||||||
routableIPs = append(routableIPs, b.appConnector.RouteInfo().Routes(true, true)...)
|
routableIPs = b.appConnector.RouteInfo().Routes(true, true)
|
||||||
}
|
}
|
||||||
routableIPs = append(routableIPs, prefs.AdvertiseRoutes().AsSlice()...)
|
routableIPs = append(routableIPs, prefs.AdvertiseRoutes().AsSlice()...)
|
||||||
hi.RoutableIPs = routableIPs
|
hi.RoutableIPs = routableIPs
|
||||||
@@ -6096,6 +6098,16 @@ func (b *LocalBackend) StreamDebugCapture(ctx context.Context, w io.Writer) erro
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *LocalBackend) AppcRouteInfo() *routeinfo.RouteInfo {
|
||||||
|
b.mu.Lock()
|
||||||
|
defer b.mu.Unlock()
|
||||||
|
if b.appConnector == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
ri := b.appConnector.RouteInfo()
|
||||||
|
return ri
|
||||||
|
}
|
||||||
|
|
||||||
func (b *LocalBackend) GetPeerEndpointChanges(ctx context.Context, ip netip.Addr) ([]magicsock.EndpointChange, error) {
|
func (b *LocalBackend) GetPeerEndpointChanges(ctx context.Context, ip netip.Addr) ([]magicsock.EndpointChange, error) {
|
||||||
pip, ok := b.e.PeerForIP(ip)
|
pip, ok := b.e.PeerForIP(ip)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"tailscale.com/appc/routeinfo"
|
||||||
"tailscale.com/client/tailscale/apitype"
|
"tailscale.com/client/tailscale/apitype"
|
||||||
"tailscale.com/clientupdate"
|
"tailscale.com/clientupdate"
|
||||||
"tailscale.com/drive"
|
"tailscale.com/drive"
|
||||||
@@ -114,6 +115,7 @@ var handler = map[string]localAPIHandler{
|
|||||||
"query-feature": (*Handler).serveQueryFeature,
|
"query-feature": (*Handler).serveQueryFeature,
|
||||||
"reload-config": (*Handler).reloadConfig,
|
"reload-config": (*Handler).reloadConfig,
|
||||||
"reset-auth": (*Handler).serveResetAuth,
|
"reset-auth": (*Handler).serveResetAuth,
|
||||||
|
"routeInfo": (*Handler).serveRouteInfo,
|
||||||
"serve-config": (*Handler).serveServeConfig,
|
"serve-config": (*Handler).serveServeConfig,
|
||||||
"set-dns": (*Handler).serveSetDNS,
|
"set-dns": (*Handler).serveSetDNS,
|
||||||
"set-expiry-sooner": (*Handler).serveSetExpirySooner,
|
"set-expiry-sooner": (*Handler).serveSetExpirySooner,
|
||||||
@@ -1387,6 +1389,26 @@ func (h *Handler) servePrefs(w http.ResponseWriter, r *http.Request) {
|
|||||||
e.Encode(prefs)
|
e.Encode(prefs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *Handler) serveRouteInfo(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if !h.PermitRead {
|
||||||
|
http.Error(w, "routeInfo access denied", http.StatusForbidden)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if r.Method != "GET" {
|
||||||
|
http.Error(w, "unsupported method", http.StatusMethodNotAllowed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var ri *routeinfo.RouteInfo
|
||||||
|
|
||||||
|
ri = h.b.AppcRouteInfo()
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
e := json.NewEncoder(w)
|
||||||
|
e.SetIndent("", "\t")
|
||||||
|
e.Encode(ri)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
type resJSON struct {
|
type resJSON struct {
|
||||||
Error string `json:",omitempty"`
|
Error string `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ func NewWatchdog(e Engine) Engine {
|
|||||||
wrap: e,
|
wrap: e,
|
||||||
logf: log.Printf,
|
logf: log.Printf,
|
||||||
fatalf: log.Fatalf,
|
fatalf: log.Fatalf,
|
||||||
maxWait: 45 * time.Second,
|
maxWait: 45 * time.Minute,
|
||||||
inFlight: make(map[inFlightKey]time.Time),
|
inFlight: make(map[inFlightKey]time.Time),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user