diff --git a/intra/tcp.go b/intra/tcp.go index 4d8d7020..d8e6a7c2 100644 --- a/intra/tcp.go +++ b/intra/tcp.go @@ -186,17 +186,18 @@ func (h *tcpHandler) Proxy(gconn *netstack.GTCPConn, src, target netip.AddrPort) return deny } - // handshake; since we assume a duplex-stream from here on - if open, err = gconn.Establish(); !open { - log.E("tcp: %s connect err %v; %s => %s for %s", cid, err, src, target, uid) - clos(gconn) - h.queueSummary(smm.done(err)) - return deny // == !open - } - if isAnyBasePid(pids) { // see udp.go:Connect - if h.dnsOverride(gconn, target, uid) { + if target.IsValid() && h.resolver.IsDnsAddr(target) { // SocketSummary not sent; x.DNSSummary supercedes it + if _, err := gconn.Establish(); err != nil { + clos(gconn) + h.queueSummary(smm.done(err)) + return deny // == !open + } + // conn closed by the resolver + core.Gx(h.proto+".dns", func() { + h.resolver.Serve(h.proto, gconn, uid) + }) return allow } // else not a dns request } // if ipn.Exit then let it connect as-is (aka exit) @@ -270,6 +271,12 @@ func (h *tcpHandler) handle(px ipn.Proxy, src net.Conn, boundSrc, target netip.A return err } + gconn := src.(*netstack.GTCPConn) + if _, err := gconn.Establish(); err != nil { + clos(pc) + return err + } + core.Go("tcp.forward."+smm.ID, func() { h.forward(src, rwext{dst, tcptimeout}, smm) // src always *gonet.TCPConn })