Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 02286e5

Browse files
authored
fix: fix netstack to forward TCP sessions to local addresses (#62)
relates to: coder/coder#14715 For CoderVPN, we need Agents to operate on a separate Unique Local Address (ULA) prefix than Tailscale, so that CoderVPN and Tailscale can both run on the same computer. This PR fixes an issue in the Tailscale netstack, where it uses the hardcoded Tailscale ULA to decide whether to forward TCP connections to localhost (127.0.0.1), rather than just checking whether the destination is an address assigned to the node. Pretty sure this is just a bug / another case of assumptions that are true for Tailscale but not for us. `acceptTCP()` makes a call to `removeSubnetAddress()` in a defer. This was originally conditional on `isTailscaleIP`, but the check for `addSubnetAddress()` on line 311 uses `isLocalIP()`. Stepping thru the code, if we accept a TCP connection for an address that is local, but not in the Tailscale service prefix (i.e. one in our new Coder service prefix), we call `removeSubnetAddress()` without ever having called `addSubnetAddress()`, and decrement the connection count on that address to -1, which is almost certainly incorrect. It worked fine for Tailscale because they could safely assume that all local addresses were also Tailscale IPs, but we can't anymore. Note also that UDP forwarding already uses `isLocalIP()` to decide whether to forward. This change passes the local `netstack` unit tests, but the real tests will be in `coder/coder` when we show that we can successfully make TCP connections.
2 parents ddd4a72 + b3b2e15 commit 02286e5

File tree

1 file changed

+4
-4
lines changed

1 file changed

+4
-4
lines changed

wgengine/netstack/netstack.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -878,17 +878,17 @@ func (ns *Impl) acceptTCP(r *tcp.ForwarderRequest) {
878878
clientRemoteAddrPort := netip.AddrPortFrom(clientRemoteIP, clientRemotePort)
879879

880880
dialIP := netaddrIPFromNetstackIP(reqDetails.LocalAddress)
881-
isTailscaleIP := tsaddr.IsTailscaleIP(dialIP)
881+
isLocal := ns.isLocalIP(dialIP)
882882

883883
dstAddrPort := netip.AddrPortFrom(dialIP, reqDetails.LocalPort)
884884

885885
if viaRange.Contains(dialIP) {
886-
isTailscaleIP = false
886+
isLocal = false
887887
dialIP = tsaddr.UnmapVia(dialIP)
888888
}
889889

890890
defer func() {
891-
if !isTailscaleIP {
891+
if !isLocal {
892892
// if this is a subnet IP, we added this in before the TCP handshake
893893
// so netstack is happy TCP-handshaking as a subnet IP
894894
ns.removeSubnetAddress(dialIP)
@@ -975,7 +975,7 @@ func (ns *Impl) acceptTCP(r *tcp.ForwarderRequest) {
975975
return
976976
}
977977
}
978-
if isTailscaleIP {
978+
if isLocal {
979979
dialIP = netaddr.IPv4(127, 0, 0, 1)
980980
}
981981
dialAddr := netip.AddrPortFrom(dialIP, uint16(reqDetails.LocalPort))

0 commit comments

Comments
 (0)