ipn/ipnlocal: connect serve config to c2n endpoint

This commit updates the VIPService c2n endpoint on client to response with actual VIPService configuration stored
in the serve config.

Fixes tailscale/corp#24510
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
This commit is contained in:
KevinLiang10
2025-01-06 11:27:11 -05:00
parent 60daa2adb8
commit 009da8a364
3 changed files with 154 additions and 34 deletions

View File

@@ -16,7 +16,9 @@ import (
"tailscale.com/ipn/ipnstate"
"tailscale.com/tailcfg"
"tailscale.com/types/ipproto"
"tailscale.com/util/mak"
"tailscale.com/util/set"
)
// ServeConfigKey returns a StateKey that stores the
@@ -655,3 +657,41 @@ func (v ServeConfigView) HasFunnelForTarget(target HostPort) bool {
}
return false
}
// ServicePortRange returns the list of tailcfg.ProtoPortRange that represents
// the proto/ports pairs that are being served by the service.
//
// Right now Tun mode is the only thing supports UDP, otherwise serve only supports TCP.
func (v ServiceConfigView) ServicePortRange() []tailcfg.ProtoPortRange {
if v.Tun() {
// If the service is in Tun mode, means service accept TCP/UDP on all ports.
return []tailcfg.ProtoPortRange{{Ports: tailcfg.PortRangeAny}}
}
tcp := int(ipproto.TCP)
// Deduplicate the ports.
servePorts := make(set.Set[uint16])
for port := range v.TCP().All() {
if port > 0 {
servePorts.Add(uint16(port))
}
}
dedupedServePorts := servePorts.Slice()
slices.Sort(dedupedServePorts)
var ranges []tailcfg.ProtoPortRange
for _, p := range dedupedServePorts {
if n := len(ranges); n > 0 && p == ranges[n-1].Ports.Last+1 {
ranges[n-1].Ports.Last = p
continue
}
ranges = append(ranges, tailcfg.ProtoPortRange{
Proto: tcp,
Ports: tailcfg.PortRange{
First: p,
Last: p,
},
})
}
return ranges
}