Commit 569280fa authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

http2: fix over-aggressive ignoring of frames while in "go away" mode

https://golang.org/cl/31727 made many of the Server Frame processors
ignore incoming frames if the connection was in shutdown mode.

The idea was that it's pointless to do work if we're about to hang up
on them in 250ms anyway for violating a protocol error.

But as of https://golang.org/cl/32412 (graceful shutdown) we can also
be in "go away" mode for ErrCodeNo, which just means to nicely tell
them to GOAWAY and because they did nothing wrong, we don't hang up in
250ms (the value of which gave the peer time to read the error before
the TCP close), but instead we keep the conn open until it's idle.

The combination of the two CLs made TestTransportAndServerSharedBodyRace_h2
flaky, since it was never seeing RST_STREAM on cancelation of requests,
and then Handlers would block forever.

Updates golang/go#17733 (fixes after bundle into std)

Change-Id: I67491c1d7124bc3cb554f9246ea7683f20b6a4e3
Reviewed-on: https://go-review.googlesource.com/32583
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarDavid Crawshaw <crawshaw@golang.org>
parent 6c4ac8bd
...@@ -1185,7 +1185,7 @@ func (sc *serverConn) processPing(f *PingFrame) error { ...@@ -1185,7 +1185,7 @@ func (sc *serverConn) processPing(f *PingFrame) error {
// PROTOCOL_ERROR." // PROTOCOL_ERROR."
return ConnectionError(ErrCodeProtocol) return ConnectionError(ErrCodeProtocol)
} }
if sc.inGoAway { if sc.inGoAway && sc.goAwayCode != ErrCodeNo {
return nil return nil
} }
sc.writeFrame(FrameWriteRequest{write: writePingAck{f}}) sc.writeFrame(FrameWriteRequest{write: writePingAck{f}})
...@@ -1194,9 +1194,6 @@ func (sc *serverConn) processPing(f *PingFrame) error { ...@@ -1194,9 +1194,6 @@ func (sc *serverConn) processPing(f *PingFrame) error {
func (sc *serverConn) processWindowUpdate(f *WindowUpdateFrame) error { func (sc *serverConn) processWindowUpdate(f *WindowUpdateFrame) error {
sc.serveG.check() sc.serveG.check()
if sc.inGoAway {
return nil
}
switch { switch {
case f.StreamID != 0: // stream-level flow control case f.StreamID != 0: // stream-level flow control
state, st := sc.state(f.StreamID) state, st := sc.state(f.StreamID)
...@@ -1229,9 +1226,6 @@ func (sc *serverConn) processWindowUpdate(f *WindowUpdateFrame) error { ...@@ -1229,9 +1226,6 @@ func (sc *serverConn) processWindowUpdate(f *WindowUpdateFrame) error {
func (sc *serverConn) processResetStream(f *RSTStreamFrame) error { func (sc *serverConn) processResetStream(f *RSTStreamFrame) error {
sc.serveG.check() sc.serveG.check()
if sc.inGoAway {
return nil
}
state, st := sc.state(f.StreamID) state, st := sc.state(f.StreamID)
if state == stateIdle { if state == stateIdle {
...@@ -1291,9 +1285,6 @@ func (sc *serverConn) processSettings(f *SettingsFrame) error { ...@@ -1291,9 +1285,6 @@ func (sc *serverConn) processSettings(f *SettingsFrame) error {
} }
return nil return nil
} }
if sc.inGoAway {
return nil
}
if err := f.ForeachSetting(sc.processSetting); err != nil { if err := f.ForeachSetting(sc.processSetting); err != nil {
return err return err
} }
...@@ -1365,7 +1356,7 @@ func (sc *serverConn) processSettingInitialWindowSize(val uint32) error { ...@@ -1365,7 +1356,7 @@ func (sc *serverConn) processSettingInitialWindowSize(val uint32) error {
func (sc *serverConn) processData(f *DataFrame) error { func (sc *serverConn) processData(f *DataFrame) error {
sc.serveG.check() sc.serveG.check()
if sc.inGoAway { if sc.inGoAway && sc.goAwayCode != ErrCodeNo {
return nil return nil
} }
data := f.Data() data := f.Data()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment