Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,8 @@ private void ProcessPingFrame(FrameHeader frameHeader)
ReadOnlySpan<byte> pingContent = _incomingBuffer.ActiveSpan.Slice(0, FrameHeader.PingLength);
long pingContentLong = BinaryPrimitives.ReadInt64BigEndian(pingContent);

if (NetEventSource.Log.IsEnabled()) Trace($"Received PING frame, content:{pingContentLong} ack: {frameHeader.AckFlag}");

if (frameHeader.AckFlag)
{
ProcessPingAck(pingContentLong);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ internal void OnDataOrHeadersReceived(Http2Connection connection)

// Send a PING
_pingCounter--;
if (NetEventSource.Log.IsEnabled()) connection.Trace($"[FlowControl] Sending RTT PING with payload {_pingCounter}");
connection.LogExceptions(connection.SendPingAsync(_pingCounter, isAck: false));
_pingSentTimestamp = now;
_state = State.PingSent;
Expand All @@ -223,6 +224,7 @@ internal void OnPingAckReceived(long payload, Http2Connection connection)
{
if (_state != State.PingSent && _state != State.TerminatingMayReceivePingAck)
{
if (NetEventSource.Log.IsEnabled()) connection.Trace($"[FlowControl] Unexpected PING ACK in state {_state}");
ThrowProtocolError();
}

Expand All @@ -236,7 +238,10 @@ internal void OnPingAckReceived(long payload, Http2Connection connection)
Debug.Assert(payload < 0);

if (_pingCounter != payload)
{
if (NetEventSource.Log.IsEnabled()) connection.Trace($"[FlowControl] Unexpected RTT PING ACK payload {payload}, should be {_pingCounter}.");
ThrowProtocolError();
}

RefreshRtt(connection);
_state = State.Waiting;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,10 @@ public async Task InitialHttp2StreamWindowSize_SentInSettingsFrame()
Assert.Equal(WindowSize, (int)entry.Value);
}

[Fact]
public Task InvalidRttPingResponse_RequestShouldFail()
[Theory]
[InlineData(0)] // Invalid PING payload
[InlineData(1)] // Unexpected PING response
public Task BadRttPingResponse_RequestShouldFail(int mode)
{
return Http2LoopbackServer.CreateClientAndServerAsync(async uri =>
{
Expand All @@ -67,13 +69,24 @@ public Task InvalidRttPingResponse_RequestShouldFail()
(int streamId, _) = await connection.ReadAndParseRequestHeaderAsync();
await connection.SendDefaultResponseHeadersAsync(streamId);
PingFrame pingFrame = await connection.ReadPingAsync(); // expect an RTT PING
await connection.SendPingAckAsync(-6666); // send an invalid PING response

if (mode == 0)
{
// Invalid PING payload
await connection.SendPingAckAsync(-6666); // send an invalid PING response
}
else
{
// Unexpected PING response
await connection.SendPingAckAsync(pingFrame.Data); // send an valid PING response
await connection.SendPingAckAsync(pingFrame.Data - 1); // send a second unexpected PING response
}

await connection.SendResponseDataAsync(streamId, new byte[] { 1, 2, 3 }, true); // otherwise fine response
},
NoAutoPingResponseHttp2Options);
}


[OuterLoop("Runs long")]
[Fact]
public async Task HighBandwidthDelayProduct_ClientStreamReceiveWindowWindowScalesUp()
Expand Down