Update dependencies
This commit is contained in:
133
vendor/tailscale.com/ipn/ipnlocal/serve.go
generated
vendored
133
vendor/tailscale.com/ipn/ipnlocal/serve.go
generated
vendored
@@ -54,8 +54,9 @@ var ErrETagMismatch = errors.New("etag mismatch")
|
||||
var serveHTTPContextKey ctxkey.Key[*serveHTTPContext]
|
||||
|
||||
type serveHTTPContext struct {
|
||||
SrcAddr netip.AddrPort
|
||||
DestPort uint16
|
||||
SrcAddr netip.AddrPort
|
||||
ForVIPService tailcfg.ServiceName // "" means local
|
||||
DestPort uint16
|
||||
|
||||
// provides funnel-specific context, nil if not funneled
|
||||
Funnel *funnelFlow
|
||||
@@ -242,8 +243,7 @@ func (b *LocalBackend) updateServeTCPPortNetMapAddrListenersLocked(ports []uint1
|
||||
}
|
||||
|
||||
addrs := nm.GetAddresses()
|
||||
for i := range addrs.Len() {
|
||||
a := addrs.At(i)
|
||||
for _, a := range addrs.All() {
|
||||
for _, p := range ports {
|
||||
addrPort := netip.AddrPortFrom(a.Addr(), p)
|
||||
if _, ok := b.serveListeners[addrPort]; ok {
|
||||
@@ -276,6 +276,12 @@ func (b *LocalBackend) setServeConfigLocked(config *ipn.ServeConfig, etag string
|
||||
return errors.New("can't reconfigure tailscaled when using a config file; config file is locked")
|
||||
}
|
||||
|
||||
if config != nil {
|
||||
if err := config.CheckValidServicesConfig(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
nm := b.netMap
|
||||
if nm == nil {
|
||||
return errors.New("netMap is nil")
|
||||
@@ -312,7 +318,7 @@ func (b *LocalBackend) setServeConfigLocked(config *ipn.ServeConfig, etag string
|
||||
bs = j
|
||||
}
|
||||
|
||||
profileID := b.pm.CurrentProfile().ID
|
||||
profileID := b.pm.CurrentProfile().ID()
|
||||
confKey := ipn.ServeConfigKey(profileID)
|
||||
if err := b.store.WriteState(confKey, bs); err != nil {
|
||||
return fmt.Errorf("writing ServeConfig to StateStore: %w", err)
|
||||
@@ -327,7 +333,7 @@ func (b *LocalBackend) setServeConfigLocked(config *ipn.ServeConfig, etag string
|
||||
if b.serveConfig.Valid() {
|
||||
has = b.serveConfig.Foreground().Contains
|
||||
}
|
||||
prevConfig.Foreground().Range(func(k string, v ipn.ServeConfigView) (cont bool) {
|
||||
for k := range prevConfig.Foreground().All() {
|
||||
if !has(k) {
|
||||
for _, sess := range b.notifyWatchers {
|
||||
if sess.sessionID == k {
|
||||
@@ -335,8 +341,7 @@ func (b *LocalBackend) setServeConfigLocked(config *ipn.ServeConfig, etag string
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -434,6 +439,105 @@ func (b *LocalBackend) HandleIngressTCPConn(ingressPeer tailcfg.NodeView, target
|
||||
handler(c)
|
||||
}
|
||||
|
||||
// tcpHandlerForVIPService returns a handler for a TCP connection to a VIP service
|
||||
// that is being served via the ipn.ServeConfig. It returns nil if the destination
|
||||
// address is not a VIP service or if the VIP service does not have a TCP handler set.
|
||||
func (b *LocalBackend) tcpHandlerForVIPService(dstAddr, srcAddr netip.AddrPort) (handler func(net.Conn) error) {
|
||||
b.mu.Lock()
|
||||
sc := b.serveConfig
|
||||
ipVIPServiceMap := b.ipVIPServiceMap
|
||||
b.mu.Unlock()
|
||||
|
||||
if !sc.Valid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
dport := dstAddr.Port()
|
||||
|
||||
dstSvc, ok := ipVIPServiceMap[dstAddr.Addr()]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
tcph, ok := sc.FindServiceTCP(dstSvc, dstAddr.Port())
|
||||
if !ok {
|
||||
b.logf("The destination service doesn't have a TCP handler set.")
|
||||
return nil
|
||||
}
|
||||
|
||||
if tcph.HTTPS() || tcph.HTTP() {
|
||||
hs := &http.Server{
|
||||
Handler: http.HandlerFunc(b.serveWebHandler),
|
||||
BaseContext: func(_ net.Listener) context.Context {
|
||||
return serveHTTPContextKey.WithValue(context.Background(), &serveHTTPContext{
|
||||
SrcAddr: srcAddr,
|
||||
ForVIPService: dstSvc,
|
||||
DestPort: dport,
|
||||
})
|
||||
},
|
||||
}
|
||||
if tcph.HTTPS() {
|
||||
// TODO(kevinliang10): just leaving this TLS cert creation as if we don't have other
|
||||
// hostnames, but for services this getTLSServeCetForPort will need a version that also take
|
||||
// in the hostname. How to store the TLS cert is still being discussed.
|
||||
hs.TLSConfig = &tls.Config{
|
||||
GetCertificate: b.getTLSServeCertForPort(dport, dstSvc),
|
||||
}
|
||||
return func(c net.Conn) error {
|
||||
return hs.ServeTLS(netutil.NewOneConnListener(c, nil), "", "")
|
||||
}
|
||||
}
|
||||
|
||||
return func(c net.Conn) error {
|
||||
return hs.Serve(netutil.NewOneConnListener(c, nil))
|
||||
}
|
||||
}
|
||||
|
||||
if backDst := tcph.TCPForward(); backDst != "" {
|
||||
return func(conn net.Conn) error {
|
||||
defer conn.Close()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
backConn, err := b.dialer.SystemDial(ctx, "tcp", backDst)
|
||||
cancel()
|
||||
if err != nil {
|
||||
b.logf("localbackend: failed to TCP proxy port %v (from %v) to %s: %v", dport, srcAddr, backDst, err)
|
||||
return nil
|
||||
}
|
||||
defer backConn.Close()
|
||||
if sni := tcph.TerminateTLS(); sni != "" {
|
||||
conn = tls.Server(conn, &tls.Config{
|
||||
GetCertificate: func(hi *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||
defer cancel()
|
||||
pair, err := b.GetCertPEM(ctx, sni)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cert, err := tls.X509KeyPair(pair.CertPEM, pair.KeyPEM)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &cert, nil
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
errc := make(chan error, 1)
|
||||
go func() {
|
||||
_, err := io.Copy(backConn, conn)
|
||||
errc <- err
|
||||
}()
|
||||
go func() {
|
||||
_, err := io.Copy(conn, backConn)
|
||||
errc <- err
|
||||
}()
|
||||
return <-errc
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// tcpHandlerForServe returns a handler for a TCP connection to be served via
|
||||
// the ipn.ServeConfig. The funnelFlow can be nil if this is not a funneled
|
||||
// connection.
|
||||
@@ -464,7 +568,7 @@ func (b *LocalBackend) tcpHandlerForServe(dport uint16, srcAddr netip.AddrPort,
|
||||
}
|
||||
if tcph.HTTPS() {
|
||||
hs.TLSConfig = &tls.Config{
|
||||
GetCertificate: b.getTLSServeCertForPort(dport),
|
||||
GetCertificate: b.getTLSServeCertForPort(dport, ""),
|
||||
}
|
||||
return func(c net.Conn) error {
|
||||
return hs.ServeTLS(netutil.NewOneConnListener(c, nil), "", "")
|
||||
@@ -544,7 +648,7 @@ func (b *LocalBackend) getServeHandler(r *http.Request) (_ ipn.HTTPHandlerView,
|
||||
b.logf("[unexpected] localbackend: no serveHTTPContext in request")
|
||||
return z, "", false
|
||||
}
|
||||
wsc, ok := b.webServerConfig(hostname, sctx.DestPort)
|
||||
wsc, ok := b.webServerConfig(hostname, sctx.ForVIPService, sctx.DestPort)
|
||||
if !ok {
|
||||
return z, "", false
|
||||
}
|
||||
@@ -902,7 +1006,7 @@ func allNumeric(s string) bool {
|
||||
return s != ""
|
||||
}
|
||||
|
||||
func (b *LocalBackend) webServerConfig(hostname string, port uint16) (c ipn.WebServerConfigView, ok bool) {
|
||||
func (b *LocalBackend) webServerConfig(hostname string, forVIPService tailcfg.ServiceName, port uint16) (c ipn.WebServerConfigView, ok bool) {
|
||||
key := ipn.HostPort(fmt.Sprintf("%s:%v", hostname, port))
|
||||
|
||||
b.mu.Lock()
|
||||
@@ -911,15 +1015,18 @@ func (b *LocalBackend) webServerConfig(hostname string, port uint16) (c ipn.WebS
|
||||
if !b.serveConfig.Valid() {
|
||||
return c, false
|
||||
}
|
||||
if forVIPService != "" {
|
||||
return b.serveConfig.FindServiceWeb(forVIPService, key)
|
||||
}
|
||||
return b.serveConfig.FindWeb(key)
|
||||
}
|
||||
|
||||
func (b *LocalBackend) getTLSServeCertForPort(port uint16) func(hi *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||
func (b *LocalBackend) getTLSServeCertForPort(port uint16, forVIPService tailcfg.ServiceName) func(hi *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||
return func(hi *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||
if hi == nil || hi.ServerName == "" {
|
||||
return nil, errors.New("no SNI ServerName")
|
||||
}
|
||||
_, ok := b.webServerConfig(hi.ServerName, port)
|
||||
_, ok := b.webServerConfig(hi.ServerName, forVIPService, port)
|
||||
if !ok {
|
||||
return nil, errors.New("no webserver configured for name/port")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user