diff --git a/wgengine/netstack/netstack.go b/wgengine/netstack/netstack.go index f513a21af963b..d85c9975173b2 100644 --- a/wgengine/netstack/netstack.go +++ b/wgengine/netstack/netstack.go @@ -1000,6 +1000,22 @@ func (ns *Impl) forwardTCP(getClient func(...tcpip.SettableSocketOption) *gonet. var stdDialer net.Dialer server, err := stdDialer.DialContext(ctx, "tcp", dialAddrStr) if err != nil { + // Coder: Retry with loopback IPv6 if the dial was for 127.0.0.1. + if dialAddr.Addr().Is4() && dialAddr.Addr().String() == "127.0.0.1" { + ipv6DialAddr := netip.AddrPortFrom(netip.IPv6Loopback(), dialAddr.Port()) + server, err = stdDialer.DialContext(ctx, "tcp", ipv6DialAddr.String()) + if err == nil { + dialAddr = ipv6DialAddr + dialAddrStr = ipv6DialAddr.String() + if debugNetstack() { + ns.logf("[coder] netstack: successful IPv4 loopback => IPv6 loopback hit: original = %s, new = %s", dialAddrStr, ipv6DialAddr.String()) + } + } else { + ns.logf("netstack: could not connect to local server at %s (or %s)", dialAddrStr, ipv6DialAddr.String(), err) + return + } + } + ns.logf("netstack: could not connect to local server at %s: %v", dialAddr.String(), err) return }