Fix data race in synRcvdState.
When checking the length of the acceptedChan we should hold the endpoint mutex otherwise a syn received while the listening socket is being closed can result in a data race where the cleanupLocked routine sets acceptedChan to nil while a handshake goroutine in progress could try and check it at the same time. PiperOrigin-RevId: 251537697
This commit is contained in:
parent
7398f013f0
commit
e0fb921205
|
@ -284,14 +284,19 @@ func (h *handshake) synRcvdState(s *segment) *tcpip.Error {
|
|||
// listenContext is also used by a tcp.Forwarder and in that
|
||||
// context we do not have a listening endpoint to check the
|
||||
// backlog. So skip this check if listenEP is nil.
|
||||
if h.listenEP != nil && len(h.listenEP.acceptedChan) == cap(h.listenEP.acceptedChan) {
|
||||
// If there is no space in the accept queue to accept
|
||||
// this endpoint then silently drop this ACK. The peer
|
||||
// will anyway resend the ack and we can complete the
|
||||
// connection the next time it's retransmitted.
|
||||
h.ep.stack.Stats().TCP.ListenOverflowAckDrop.Increment()
|
||||
h.ep.stack.Stats().DroppedPackets.Increment()
|
||||
return nil
|
||||
if h.listenEP != nil {
|
||||
h.listenEP.mu.Lock()
|
||||
if len(h.listenEP.acceptedChan) == cap(h.listenEP.acceptedChan) {
|
||||
h.listenEP.mu.Unlock()
|
||||
// If there is no space in the accept queue to accept
|
||||
// this endpoint then silently drop this ACK. The peer
|
||||
// will anyway resend the ack and we can complete the
|
||||
// connection the next time it's retransmitted.
|
||||
h.ep.stack.Stats().TCP.ListenOverflowAckDrop.Increment()
|
||||
h.ep.stack.Stats().DroppedPackets.Increment()
|
||||
return nil
|
||||
}
|
||||
h.listenEP.mu.Unlock()
|
||||
}
|
||||
// If the timestamp option is negotiated and the segment does
|
||||
// not carry a timestamp option then the segment must be dropped
|
||||
|
|
Loading…
Reference in New Issue