summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/transport/ping
diff options
context:
space:
mode:
authorBrian Geffon <bgeffon@google.com>2018-08-07 07:56:08 -0700
committerShentubot <shentubot@google.com>2018-08-07 07:57:20 -0700
commitd839dc13c689f853fd87c495c26208048a540919 (patch)
tree4776c32bdcef43e3a02d6d1a75d6d4457a6d697e /pkg/tcpip/transport/ping
parent9752174a7f211328c0ff59f8ed6c51325a6fc23d (diff)
Netstack doesn't handle sending after SHUT_WR correctly.
PiperOrigin-RevId: 207715032 Change-Id: I7b6690074c5be283145192895d706a92e921b22c
Diffstat (limited to 'pkg/tcpip/transport/ping')
-rw-r--r--pkg/tcpip/transport/ping/endpoint.go26
1 files changed, 17 insertions, 9 deletions
diff --git a/pkg/tcpip/transport/ping/endpoint.go b/pkg/tcpip/transport/ping/endpoint.go
index a22684de9..f097ac057 100644
--- a/pkg/tcpip/transport/ping/endpoint.go
+++ b/pkg/tcpip/transport/ping/endpoint.go
@@ -71,12 +71,14 @@ type endpoint struct {
// The following fields are protected by the mu mutex.
mu sync.RWMutex `state:"nosave"`
sndBufSize int
- id stack.TransportEndpointID
- state endpointState
- bindNICID tcpip.NICID
- bindAddr tcpip.Address
- regNICID tcpip.NICID
- route stack.Route `state:"manual"`
+ // shutdownFlags represent the current shutdown state of the endpoint.
+ shutdownFlags tcpip.ShutdownFlags
+ id stack.TransportEndpointID
+ state endpointState
+ bindNICID tcpip.NICID
+ bindAddr tcpip.Address
+ regNICID tcpip.NICID
+ route stack.Route `state:"manual"`
}
func newEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, waiterQueue *waiter.Queue) *endpoint {
@@ -93,7 +95,7 @@ func newEndpoint(stack *stack.Stack, netProto tcpip.NetworkProtocolNumber, waite
// associated with it.
func (e *endpoint) Close() {
e.mu.Lock()
-
+ e.shutdownFlags = tcpip.ShutdownRead | tcpip.ShutdownWrite
switch e.state {
case stateBound, stateConnected:
e.stack.UnregisterTransportEndpoint(e.regNICID, []tcpip.NetworkProtocolNumber{e.netProto}, ProtocolNumber4, e.id)
@@ -205,6 +207,11 @@ func (e *endpoint) Write(p tcpip.Payload, opts tcpip.WriteOptions) (uintptr, *tc
e.mu.RLock()
defer e.mu.RUnlock()
+ // If we've shutdown with SHUT_WR we are in an invalid state for sending.
+ if e.shutdownFlags&tcpip.ShutdownWrite != 0 {
+ return 0, tcpip.ErrClosedForSend
+ }
+
// Prepare for write.
for {
retry, err := e.prepareForWrite(to)
@@ -465,8 +472,9 @@ func (*endpoint) ConnectEndpoint(tcpip.Endpoint) *tcpip.Error {
// Shutdown closes the read and/or write end of the endpoint connection
// to its peer.
func (e *endpoint) Shutdown(flags tcpip.ShutdownFlags) *tcpip.Error {
- e.mu.RLock()
- defer e.mu.RUnlock()
+ e.mu.Lock()
+ defer e.mu.Unlock()
+ e.shutdownFlags |= flags
if e.state != stateConnected {
return tcpip.ErrNotConnected