diff --git a/wgengine/magicsock/magicsock.go b/wgengine/magicsock/magicsock.go index 3d7b16f30..f1721e1d9 100644 --- a/wgengine/magicsock/magicsock.go +++ b/wgengine/magicsock/magicsock.go @@ -2444,7 +2444,10 @@ func (c *Conn) handleDiscoMessage(msg []byte, src epAddr, shouldBeRelayHandshake if !nodeHasCap(c.filt, c.peers.At(peerI), c.self, tailcfg.PeerCapabilityRelay) { return } - c.allocRelayEndpointPub.Publish(UDPRelayAllocReq{ + // [Conn.mu] must not be held while publishing, or [Conn.onUDPRelayAllocResp] + // can deadlock as the req sub and resp pub are the same goroutine. + // See #17830. + go c.allocRelayEndpointPub.Publish(UDPRelayAllocReq{ RxFromDiscoKey: sender, RxFromNodeKey: nodeKey, Message: req,