service: Don't hold listener lock while handing off a connection (#1939)

This commit is contained in:
John Maguire authored and GitHub committed 2026-10-15 15:14:39 -04:00
1 parent afbdc87ed9
commit 42597dda7d
3 files changed
+173 -13

No files matched your search

+9 -3
View File
@@ -231,6 +231,7 @@ func (s *Service) Listen(network, address string) (net.Listener, error) {
s: s,
addr: addr,
accept: make(chan net.Conn),
closed: make(chan struct{}),
}
s.mu.Lock()
@@ -257,9 +258,8 @@ func (s *Service) tcpHandler(r *tcp.ForwarderRequest) {
endpointID := r.ID()
s.mu.Lock()
defer s.mu.Unlock()
l, ok := s.mu.listeners[endpointID.LocalPort]
s.mu.Unlock()
if !ok {
r.Complete(true)
return
@@ -275,6 +275,12 @@ func (s *Service) tcpHandler(r *tcp.ForwarderRequest) {
r.Complete(false)
ep.SocketOptions().SetKeepAlive(true)
// The handoff blocks until Accept is called, so it must not hold s.mu or a
// listener nobody accepts from stalls every other port.
conn := gonet.NewTCPConn(&wq, ep)
l.accept <- conn
select {
case l.accept <- conn:
case <-l.closed:
_ = conn.Close()
}
}