ipn/ipnlocal: add VIPServices hash to return body of vip-services c2n endpoint

This commit updates the return body of c2n endpoint /vip-services to keep hash generation logic on client side.

Updates tailscale/corp#24510

Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
This commit is contained in:
KevinLiang10 2025-01-09 16:45:04 -05:00
parent cd795d8a7f
commit 2af255790d
3 changed files with 22 additions and 4 deletions

View File

@ -274,8 +274,12 @@ func handleC2NSetNetfilterKind(b *LocalBackend, w http.ResponseWriter, r *http.R
func handleC2NVIPServicesGet(b *LocalBackend, w http.ResponseWriter, r *http.Request) {
b.logf("c2n: GET /vip-services received")
var res tailcfg.C2NVIPServicesResponse
res.VIPServices = b.VIPServices()
res.ServicesHash = b.vipServiceHash(res.VIPServices)
json.NewEncoder(w).Encode(b.VIPServices())
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(res)
}
func handleC2NUpdateGet(b *LocalBackend, w http.ResponseWriter, r *http.Request) {

View File

@ -5022,7 +5022,7 @@ func (b *LocalBackend) applyPrefsToHostinfoLocked(hi *tailcfg.Hostinfo, prefs ip
}
hi.SSH_HostKeys = sshHostKeys
hi.ServicesHash = b.vipServiceHashLocked(prefs)
hi.ServicesHash = b.vipServiceHash(b.vipServicesFromPrefsLocked(prefs))
// The Hostinfo.WantIngress field tells control whether this node wants to
// be wired up for ingress connections. If harmless if it's accidentally
@ -7661,8 +7661,7 @@ func (b *LocalBackend) VIPServices() []*tailcfg.VIPService {
return b.vipServicesFromPrefsLocked(b.pm.CurrentPrefs())
}
func (b *LocalBackend) vipServiceHashLocked(prefs ipn.PrefsView) string {
services := b.vipServicesFromPrefsLocked(prefs)
func (b *LocalBackend) vipServiceHash(services []*tailcfg.VIPService) string {
if len(services) == 0 {
return ""
}

View File

@ -102,3 +102,18 @@ type C2NTLSCertInfo struct {
// TODO(bradfitz): add fields for whether an ACME fetch is currently in
// process and when it started, etc.
}
// C2NVIPServicesResponse is the response (from node to control) from the
// /vip-services handler.
//
// It returns the list of VIPServices that the node is currently serving with
// their port info and whether they are active or not. It also returns a hash of
// the response to allow the control server to detect changes.
type C2NVIPServicesResponse struct {
// VIPServices is the list of VIP services that the node is currently serving.
VIPServices []*VIPService `json:",omitempty"`
// ServicesHash is the hash of VIPServices to allow the control server to detect
// changes. This value matches what is reported in latest [Hostinfo.ServicesHash].
ServicesHash string
}