mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-11-28 16:26:10 +03:00
h2: Pad RST_STREAM frames
Clients sending too many RST_STREAM is an irregular behavior. Hack in a preceding END_STREAM DATA frame padded towards [48, 72] before RST_STREAM so that the TLS record looks like a HEADERS frame. The server often replies to this with a WINDOW_UPDATE because padding is accounted in flow control. Whether this constitudes a new irregular behavior is still unclear.
This commit is contained in:
parent
940d123a5d
commit
ec982cc608
@ -15,6 +15,7 @@
|
|||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#include "base/metrics/histogram_functions.h"
|
#include "base/metrics/histogram_functions.h"
|
||||||
#include "base/metrics/histogram_macros.h"
|
#include "base/metrics/histogram_macros.h"
|
||||||
|
#include "base/rand_util.h"
|
||||||
#include "base/single_thread_task_runner.h"
|
#include "base/single_thread_task_runner.h"
|
||||||
#include "base/stl_util.h"
|
#include "base/stl_util.h"
|
||||||
#include "base/strings/abseil_string_conversions.h"
|
#include "base/strings/abseil_string_conversions.h"
|
||||||
@ -2222,6 +2223,25 @@ void SpdySession::EnqueueResetStreamFrame(spdy::SpdyStreamId stream_id,
|
|||||||
DCHECK(buffered_spdy_framer_.get());
|
DCHECK(buffered_spdy_framer_.get());
|
||||||
std::unique_ptr<spdy::SpdySerializedFrame> rst_frame(
|
std::unique_ptr<spdy::SpdySerializedFrame> rst_frame(
|
||||||
buffered_spdy_framer_->CreateRstStream(stream_id, error_code));
|
buffered_spdy_framer_->CreateRstStream(stream_id, error_code));
|
||||||
|
// Can't send padding if the send window is very tight.
|
||||||
|
if (session_send_window_size_ >= 72) {
|
||||||
|
constexpr int kNonPaddingSize =
|
||||||
|
spdy::kDataFrameMinimumSize + spdy::kRstStreamFrameSize;
|
||||||
|
uint8_t padding_length = base::RandInt(48, 72) - kNonPaddingSize;
|
||||||
|
size_t expected_length = kNonPaddingSize + padding_length;
|
||||||
|
spdy::SpdyFrameBuilder builder(expected_length);
|
||||||
|
builder.BeginNewFrame(spdy::SpdyFrameType::DATA,
|
||||||
|
spdy::DATA_FLAG_FIN | spdy::DATA_FLAG_PADDED,
|
||||||
|
stream_id, padding_length);
|
||||||
|
builder.WriteUInt8(padding_length - 1);
|
||||||
|
std::string padding(padding_length - 1, 0);
|
||||||
|
builder.WriteBytes(padding.data(), padding.size());
|
||||||
|
builder.BeginNewFrame(spdy::SpdyFrameType::RST_STREAM, 0, stream_id, 4);
|
||||||
|
builder.WriteUInt32(error_code);
|
||||||
|
DCHECK_EQ(expected_length, builder.length());
|
||||||
|
rst_frame = std::make_unique<spdy::SpdySerializedFrame>(builder.take());
|
||||||
|
DecreaseSendWindowSize(padding_length);
|
||||||
|
}
|
||||||
|
|
||||||
EnqueueSessionWrite(priority, spdy::SpdyFrameType::RST_STREAM,
|
EnqueueSessionWrite(priority, spdy::SpdyFrameType::RST_STREAM,
|
||||||
std::move(rst_frame));
|
std::move(rst_frame));
|
||||||
|
Loading…
Reference in New Issue
Block a user