ipn/ipnlocal: add support for funnel in tsnet

Previously the part that handled Funnel connections was not
aware of any listeners that tsnet.Servers might have had open
so it would check against the ServeConfig and fail.

Adding a ServeConfig for a TCP proxy was also not suitable in this
scenario as that would mean creating two different listeners and have
one forward to the other, which really meant that you could not have
funnel and tailnet-only listeners on the same port.

This also introduces the ipn.FunnelConn as a way for users to identify
whether the call is coming over funnel or not. Currently it only holds
the underlying conn and the target as presented in the "Tailscale-Ingress-Target"
header.

Signed-off-by: Maisem Ali <maisem@tailscale.com>
This commit is contained in:
Maisem Ali
2023-03-08 12:36:41 -08:00
committed by Maisem Ali
parent dad78f31f3
commit b797f773c7
6 changed files with 222 additions and 5 deletions
+25
View File
@@ -3,6 +3,11 @@
package ipn
import (
"net"
"net/netip"
)
// ServeConfigKey returns a StateKey that stores the
// JSON-encoded ServeConfig for a config profile.
func ServeConfigKey(profileID ProfileID) StateKey {
@@ -29,6 +34,26 @@ type ServeConfig struct {
// There is no implicit port 443. It must contain a colon.
type HostPort string
// A FunnelConn wraps a net.Conn that is coming over a
// Funnel connection. It can be used to determine further
// information about the connection, like the source address
// and the target SNI name.
type FunnelConn struct {
// Conn is the underlying connection.
net.Conn
// Target is what was presented in the "Tailscale-Ingress-Target"
// HTTP header.
Target HostPort
// Src is the source address of the connection.
// This is the address of the client that initiated the
// connection, not the address of the Tailscale Funnel
// node which is relaying the connection. That address
// can be found in Conn.RemoteAddr.
Src netip.AddrPort
}
// WebServerConfig describes a web server's configuration.
type WebServerConfig struct {
Handlers map[string]*HTTPHandler // mountPoint => handler