proxymap, various: distinguish between different protocols

Previously, we were registering TCP and UDP connections in the same map,
which could result in erroneously removing a mapping if one of the two
connections completes while the other one is still active.

Add a "proto string" argument to these functions to avoid this.
Additionally, take the "proto" argument in LocalAPI, and plumb that
through from the CLI and add a new LocalClient method.

Updates tailscale/corp#20600

Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I35d5efaefdfbf4721e315b8ca123f0c8af9125fb
This commit is contained in:
Andrew Dunham
2024-06-06 14:48:40 -04:00
parent 2cb408f9b1
commit 45d2f4301f
12 changed files with 89 additions and 30 deletions

View File

@@ -1328,8 +1328,8 @@ func (ns *Impl) forwardTCP(getClient func(...tcpip.SettableSocketOption) *gonet.
backendLocalAddr := server.LocalAddr().(*net.TCPAddr)
backendLocalIPPort := netaddr.Unmap(backendLocalAddr.AddrPort())
ns.pm.RegisterIPPortIdentity(backendLocalIPPort, clientRemoteIP)
defer ns.pm.UnregisterIPPortIdentity(backendLocalIPPort)
ns.pm.RegisterIPPortIdentity("tcp", backendLocalIPPort, clientRemoteIP)
defer ns.pm.UnregisterIPPortIdentity("tcp", backendLocalIPPort)
connClosed := make(chan error, 2)
go func() {
_, err := io.Copy(server, client)
@@ -1533,7 +1533,7 @@ func (ns *Impl) forwardUDP(client *gonet.UDPConn, clientAddr, dstAddr netip.Addr
ns.logf("could not get backend local IP:port from %v:%v", backendLocalAddr.IP, backendLocalAddr.Port)
}
if isLocal {
ns.pm.RegisterIPPortIdentity(backendLocalIPPort, dstAddr.Addr())
ns.pm.RegisterIPPortIdentity("udp", backendLocalIPPort, clientAddr.Addr())
}
ctx, cancel := context.WithCancel(context.Background())
@@ -1549,7 +1549,7 @@ func (ns *Impl) forwardUDP(client *gonet.UDPConn, clientAddr, dstAddr netip.Addr
}
timer := time.AfterFunc(idleTimeout, func() {
if isLocal {
ns.pm.UnregisterIPPortIdentity(backendLocalIPPort)
ns.pm.UnregisterIPPortIdentity("udp", backendLocalIPPort)
}
ns.logf("netstack: UDP session between %s and %s timed out", backendListenAddr, backendRemoteAddr)
cancel()