Issue #4967 - Possible buffer corruption in HTTP/2 session failures.

Fixed test failure after merge.

Made sure the lastStreamId is updated when resetting a new
stream since it has been seen by the server and handled.

This avoids that a new stream arriving during shutdown is
interpreted as a connection failure, therefore failing all
pending streams - we want them to complete.

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
Simone Bordet 2020-07-07 11:42:16 +02:00
parent ba6a6ea67d
commit fb07bdf159
2 changed files with 4 additions and 3 deletions

View File

@ -693,14 +693,14 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
if (closed.compareAndSet(CloseState.NOT_CLOSED, CloseState.LOCALLY_CLOSED)) if (closed.compareAndSet(CloseState.NOT_CLOSED, CloseState.LOCALLY_CLOSED))
{ {
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
LOG.debug("Closing {}/{}", error, reason); LOG.debug("Closing {}/{} {}", error, reason, this);
closeFrame = newGoAwayFrame(CloseState.LOCALLY_CLOSED, error, reason); closeFrame = newGoAwayFrame(CloseState.LOCALLY_CLOSED, error, reason);
control(null, callback, closeFrame); control(null, callback, closeFrame);
return true; return true;
} }
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
LOG.debug("Ignoring close {}/{}, already closed", error, reason); LOG.debug("Ignoring close {}/{}, already closed {}", error, reason, this);
callback.succeeded(); callback.succeeded();
return false; return false;
} }
@ -1151,7 +1151,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
return lastRemoteStreamId.get(); return lastRemoteStreamId.get();
} }
private void updateLastRemoteStreamId(int streamId) protected void updateLastRemoteStreamId(int streamId)
{ {
Atomics.updateMax(lastRemoteStreamId, streamId); Atomics.updateMax(lastRemoteStreamId, streamId);
} }

View File

@ -106,6 +106,7 @@ public class HTTP2ServerSession extends HTTP2Session implements ServerParser.Lis
{ {
if (isClosed()) if (isClosed())
{ {
updateLastRemoteStreamId(streamId);
reset(new ResetFrame(streamId, ErrorCode.REFUSED_STREAM_ERROR.code), Callback.NOOP); reset(new ResetFrame(streamId, ErrorCode.REFUSED_STREAM_ERROR.code), Callback.NOOP);
} }
else else