diff options
author | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-25 07:20:26 +0000 |
---|---|---|
committer | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-25 07:20:26 +0000 |
commit | c9771defff52a434021afad7fdeb16d814901f4b (patch) | |
tree | f18baf7224467ce12d3c477bb15ba87a926c94a8 /net/quic/quic_stream_sequencer.cc | |
parent | 15be9bff681fc1195fbf96f81e53fef96c855573 (diff) | |
download | chromium_src-c9771defff52a434021afad7fdeb16d814901f4b.zip chromium_src-c9771defff52a434021afad7fdeb16d814901f4b.tar.gz chromium_src-c9771defff52a434021afad7fdeb16d814901f4b.tar.bz2 |
Land Recent QUIC Changes.
Fix 2 in 10k flakiness in QUIC EndToEndTest caused by a packet's stream
frames being ignored, but not it's ack frames.
Merge internal change: 60048409
https://codereview.chromium.org/147123004/
Improving the GuidsOrderedByTime test.
Merge internal change: 60039389
https://codereview.chromium.org/147443004/
Prevent crashing when adding a GUID to TimeWaitListManager multiple
times.
Merge internal change: 60036407
https://codereview.chromium.org/143003021/
Fixed a bug where when the first transmission is acked, all other
retransmissions are lost, even if they are still pending.
This could easily be seen in tail loss probes, where it's possible for
the RTT to suddenly jump and the first transmission get acked later than
expected, but no real loss occurs.
Merge internal change: 60031702
https://codereview.chromium.org/139173008/
QUIC test fix to reduce EndToEndTest flakiness by implementing
IsWriteBlocked() in PacketDroppingTestWriter.
Merge internal change: 60024045
https://codereview.chromium.org/136393003/
Track buffered bytes in the QuicStreamSequencer. No functional change.
Will be used for tracking flow control windows in future.
Merge internal change: 60012379
https://codereview.chromium.org/139173007/
QUIC - minor clean up while merging internal changes.
Merge internal change: 59956956
https://codereview.chromium.org/147393002/
DFATAL and return if QuicConnection::SendOrQueuePacket is called with a
NULL packet, in the hope that this avoids a crash.
Merge internal change: 59920289
https://codereview.chromium.org/141743003/
Abandon all retransmissions of crypto packets as soon as one is acked.
This was causing a loss event when a crypto packet was retransmitted and
the original crypto packet was acked.
Merge internal change: 59913834
https://codereview.chromium.org/143523015/
R=rch@chromium.org
Review URL: https://codereview.chromium.org/147293003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@247084 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/quic/quic_stream_sequencer.cc')
-rw-r--r-- | net/quic/quic_stream_sequencer.cc | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/net/quic/quic_stream_sequencer.cc b/net/quic/quic_stream_sequencer.cc index 8696e7c..145a377 100644 --- a/net/quic/quic_stream_sequencer.cc +++ b/net/quic/quic_stream_sequencer.cc @@ -20,7 +20,8 @@ QuicStreamSequencer::QuicStreamSequencer(ReliableQuicStream* quic_stream) num_bytes_consumed_(0), max_frame_memory_(numeric_limits<size_t>::max()), close_offset_(numeric_limits<QuicStreamOffset>::max()), - blocked_(false) { + blocked_(false), + num_bytes_buffered_(0) { } QuicStreamSequencer::QuicStreamSequencer(size_t max_frame_memory, @@ -29,7 +30,8 @@ QuicStreamSequencer::QuicStreamSequencer(size_t max_frame_memory, num_bytes_consumed_(0), max_frame_memory_(max_frame_memory), close_offset_(numeric_limits<QuicStreamOffset>::max()), - blocked_(false) { + blocked_(false), + num_bytes_buffered_(0) { if (max_frame_memory < kMaxPacketSize) { LOG(DFATAL) << "Setting max frame memory to " << max_frame_memory << ". Some frames will be impossible to handle."; @@ -98,6 +100,9 @@ bool QuicStreamSequencer::OnStreamFrame(const QuicStreamFrame& frame) { IOVector data; data.AppendIovec(frame.data.iovec(), frame.data.Size()); + + // If the frame has arrived in-order then we can process it immediately, only + // buffering if the stream is unable to process it. if (!blocked_ && byte_offset == num_bytes_consumed_) { DVLOG(1) << "Processing byte offset " << byte_offset; size_t bytes_consumed = 0; @@ -117,18 +122,21 @@ bool QuicStreamSequencer::OnStreamFrame(const QuicStreamFrame& frame) { FlushBufferedFrames(); return true; // it's safe to ack this frame. } else { - // Set ourselves up to buffer what's left + // Set ourselves up to buffer what's left. data_len -= bytes_consumed; data.Consume(bytes_consumed); byte_offset += bytes_consumed; } } + + // Buffer any remaining data to be consumed by the stream when ready. for (size_t i = 0; i < data.Size(); ++i) { DVLOG(1) << "Buffering stream data at offset " << byte_offset; - frames_.insert(make_pair(byte_offset, string( - static_cast<char*>(data.iovec()[i].iov_base), - data.iovec()[i].iov_len))); - byte_offset += data.iovec()[i].iov_len; + const iovec& iov = data.iovec()[i]; + frames_.insert(make_pair( + byte_offset, string(static_cast<char*>(iov.iov_base), iov.iov_len))); + byte_offset += iov.iov_len; + num_bytes_buffered_ += iov.iov_len; } return true; } @@ -157,6 +165,7 @@ bool QuicStreamSequencer::MaybeCloseStream() { // equal, but error handling seems silly at this point. stream_->OnFinRead(); frames_.clear(); + num_bytes_buffered_ = 0; return true; } return false; @@ -208,7 +217,7 @@ int QuicStreamSequencer::Readv(const struct iovec* iov, size_t iov_len) { } if (it->second.size() == frame_offset) { // We've copied this whole frame - num_bytes_consumed_ += it->second.size(); + RecordBytesConsumed(it->second.size()); frames_.erase(it); it = frames_.begin(); frame_offset = 0; @@ -219,7 +228,7 @@ int QuicStreamSequencer::Readv(const struct iovec* iov, size_t iov_len) { frames_.insert(make_pair(it->first + frame_offset, it->second.substr(frame_offset))); frames_.erase(frames_.begin()); - num_bytes_consumed_ += frame_offset; + RecordBytesConsumed(frame_offset); } return num_bytes_consumed_ - initial_bytes_consumed; } @@ -241,6 +250,7 @@ void QuicStreamSequencer::MarkConsumed(size_t num_bytes_consumed) { if (it->first + it->second.length() <= end_offset) { num_bytes_consumed_ += it->second.length(); + num_bytes_buffered_ -= it->second.length(); // This chunk is entirely consumed. frames_.erase(it); continue; @@ -248,7 +258,7 @@ void QuicStreamSequencer::MarkConsumed(size_t num_bytes_consumed) { // Partially consume this frame. size_t delta = end_offset - it->first; - num_bytes_consumed_ += delta; + RecordBytesConsumed(delta); frames_.insert(make_pair(end_offset, it->second.substr(delta))); frames_.erase(it); break; @@ -286,7 +296,7 @@ void QuicStreamSequencer::FlushBufferedFrames() { string* data = &it->second; size_t bytes_consumed = stream_->ProcessRawData(data->c_str(), data->size()); - num_bytes_consumed_ += bytes_consumed; + RecordBytesConsumed(bytes_consumed); if (MaybeCloseStream()) { return; } @@ -306,4 +316,9 @@ void QuicStreamSequencer::FlushBufferedFrames() { MaybeCloseStream(); } +void QuicStreamSequencer::RecordBytesConsumed(size_t bytes_consumed) { + num_bytes_consumed_ += bytes_consumed; + num_bytes_buffered_ -= bytes_consumed; +} + } // namespace net |