diff options
author | Bhasker Hariharan <bhaskerh@google.com> | 2020-10-27 18:11:46 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-10-27 18:13:46 -0700 |
commit | 24c33de748425e918033267313a4414b8ceb9727 (patch) | |
tree | f429c4a4ecb260936e9af0b09bec9a0466b869fc /pkg/tcpip | |
parent | 1c2836da37261c47cb8372e3ae5a49adab369694 (diff) |
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
Diffstat (limited to 'pkg/tcpip')
-rw-r--r-- | pkg/tcpip/transport/udp/endpoint.go | 16 |
1 files changed, 12 insertions, 4 deletions
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() } } |