mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-11 13:18:53 +00:00
ipn/ipnlocal: Support TCP and Web VIP services
This commit intend to provide support for TCP and Web VIP services and also allow user to use Tun for VIP services if they want to. The commit includes: 1.Setting TCP intercept function for VIP Services. 2.Update netstack to send packet written from WG to netStack handler for VIP service. 3.Return correct TCP hander for VIP services when netstack acceptTCP. This commit also includes unit tests for if the local backend setServeConfig would set correct TCP intercept function and test if a hander gets returned when getting TCPHandlerForDst. The shouldProcessInbound check is not unit tested since the test result just depends on mocked functions. There should be an integration test to cover shouldProcessInbound and if the returned TCP handler actually does what the serveConfig says. Updates tailscale/corp#24604 Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
This commit is contained in:
19
types/netmap/IPServiceMappings.go
Normal file
19
types/netmap/IPServiceMappings.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package netmap
|
||||
|
||||
import "net/netip"
|
||||
|
||||
// IPServiceMappings maps IP addresses to service names. This is the inverse of
|
||||
// [ServiceIPMappings], and is used to inform clients which services is an VIP
|
||||
// address associated with. This is set to b.ipVIPServiceMap every time the
|
||||
// netmap is updated. This is used to reduce the cost for looking up the service
|
||||
// name for the dst IP address in the netStack packet processing workflow.
|
||||
//
|
||||
// This is of the form:
|
||||
//
|
||||
// {
|
||||
// "100.65.32.1": "svc:samba",
|
||||
// "fd7a:115c:a1e0::1234": "svc:samba",
|
||||
// "100.102.42.3": "svc:web",
|
||||
// "fd7a:115c:a1e0::abcd": "svc:web",
|
||||
// }
|
||||
type IPServiceMappings map[netip.Addr]string
|
@@ -101,6 +101,54 @@ func (nm *NetworkMap) GetAddresses() views.Slice[netip.Prefix] {
|
||||
return nm.SelfNode.Addresses()
|
||||
}
|
||||
|
||||
// GetVIPServiceIPMap returns a map of service names to the slice of
|
||||
// VIP addresses that correspond to the service. The service names are
|
||||
// with the prefix "svc:".
|
||||
//
|
||||
// TODO(corp##25997): cache the result of decoding the capmap so that
|
||||
// we don't have to decode it multiple times after each netmap update.
|
||||
func (nm *NetworkMap) GetVIPServiceIPMap() tailcfg.ServiceIPMappings {
|
||||
if nm == nil {
|
||||
return nil
|
||||
}
|
||||
if !nm.SelfNode.Valid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
ipMaps, err := tailcfg.UnmarshalNodeCapJSON[tailcfg.ServiceIPMappings](nm.SelfNode.CapMap().AsMap(), tailcfg.NodeAttrServiceHost)
|
||||
if len(ipMaps) != 1 || err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return ipMaps[0]
|
||||
}
|
||||
|
||||
// GetIPVIPServiceMap returns a map of VIP addresses to the service
|
||||
// names that has the VIP address. The service names are with the
|
||||
// prefix "svc:".
|
||||
func (nm *NetworkMap) GetIPVIPServiceMap() IPServiceMappings {
|
||||
var res IPServiceMappings
|
||||
if nm == nil {
|
||||
return res
|
||||
}
|
||||
|
||||
if !nm.SelfNode.Valid() {
|
||||
return res
|
||||
}
|
||||
|
||||
serviceIPMap := nm.GetVIPServiceIPMap()
|
||||
if serviceIPMap == nil {
|
||||
return res
|
||||
}
|
||||
res = make(IPServiceMappings)
|
||||
for svc, addrs := range serviceIPMap {
|
||||
for _, addr := range addrs {
|
||||
res[addr] = svc
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// AnyPeersAdvertiseRoutes reports whether any peer is advertising non-exit node routes.
|
||||
func (nm *NetworkMap) AnyPeersAdvertiseRoutes() bool {
|
||||
for _, p := range nm.Peers {
|
||||
|
Reference in New Issue
Block a user