From 24c33de748425e918033267313a4414b8ceb9727 Mon Sep 17 00:00:00 2001 From: Bhasker Hariharan Date: Tue, 27 Oct 2020 18:11:46 -0700 Subject: Wake up any waiters on an ICMP error on UDP socket. This change wakes up any waiters when we receive an ICMP port unreachable control packet on an UDP socket as well as sets waiter.EventErr in the result returned by Readiness() when e.lastError is not nil. The latter is required where an epoll()/poll() is done after the error is already handled since we will never notify again in such cases. PiperOrigin-RevId: 339370469 --- pkg/tcpip/transport/udp/endpoint.go | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'pkg') diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index d31177eb7..cdb5127ab 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -1369,6 +1369,12 @@ func (e *endpoint) Readiness(mask waiter.EventMask) waiter.EventMask { e.rcvMu.Unlock() } + e.lastErrorMu.Lock() + hasError := e.lastError != nil + e.lastErrorMu.Unlock() + if hasError { + result |= waiter.EventErr + } return result } @@ -1468,14 +1474,16 @@ func (e *endpoint) HandlePacket(r *stack.Route, id stack.TransportEndpointID, pk func (e *endpoint) HandleControlPacket(id stack.TransportEndpointID, typ stack.ControlType, extra uint32, pkt *stack.PacketBuffer) { if typ == stack.ControlPortUnreachable { e.mu.RLock() - defer e.mu.RUnlock() - if e.state == StateConnected { e.lastErrorMu.Lock() - defer e.lastErrorMu.Unlock() - e.lastError = tcpip.ErrConnectionRefused + e.lastErrorMu.Unlock() + e.mu.RUnlock() + + e.waiterQueue.Notify(waiter.EventErr) + return } + e.mu.RUnlock() } } -- cgit v1.2.3