Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(207)

Side by Side Diff: net/quic/quic_stream_sequencer.cc

Issue 12334063: Land recent QUIC changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: more EXPECT_FALSE Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/quic/quic_stream_sequencer.h ('k') | net/quic/quic_stream_sequencer_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/quic/quic_stream_sequencer.h" 5 #include "net/quic/quic_stream_sequencer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 26 matching lines...) Expand all
37 } 37 }
38 38
39 QuicStreamSequencer::~QuicStreamSequencer() { 39 QuicStreamSequencer::~QuicStreamSequencer() {
40 } 40 }
41 41
42 bool QuicStreamSequencer::WillAcceptStreamFrame( 42 bool QuicStreamSequencer::WillAcceptStreamFrame(
43 const QuicStreamFrame& frame) const { 43 const QuicStreamFrame& frame) const {
44 size_t data_len = frame.data.size(); 44 size_t data_len = frame.data.size();
45 DCHECK_LE(data_len, max_frame_memory_); 45 DCHECK_LE(data_len, max_frame_memory_);
46 46
47 if (IsDuplicate(frame)) {
48 return true;
49 }
47 QuicStreamOffset byte_offset = frame.offset; 50 QuicStreamOffset byte_offset = frame.offset;
48 if (byte_offset < num_bytes_consumed_ ||
49 frames_.find(byte_offset) != frames_.end()) {
50 return false;
51 }
52 if (data_len > max_frame_memory_) { 51 if (data_len > max_frame_memory_) {
53 // We're never going to buffer this frame and we can't pass it up. 52 // We're never going to buffer this frame and we can't pass it up.
54 // The stream might only consume part of it and we'd need a partial ack. 53 // The stream might only consume part of it and we'd need a partial ack.
55 // 54 //
56 // Ideally this should never happen, as we check that 55 // Ideally this should never happen, as we check that
57 // max_frame_memory_ > kMaxPacketSize and lower levels should reject 56 // max_frame_memory_ > kMaxPacketSize and lower levels should reject
58 // frames larger than that. 57 // frames larger than that.
59 return false; 58 return false;
60 } 59 }
61 if (byte_offset + data_len - num_bytes_consumed_ > max_frame_memory_) { 60 if (byte_offset + data_len - num_bytes_consumed_ > max_frame_memory_) {
62 // We can buffer this but not right now. Toss it. 61 // We can buffer this but not right now. Toss it.
63 // It might be worth trying an experiment where we try best-effort buffering 62 // It might be worth trying an experiment where we try best-effort buffering
64 return false; 63 return false;
65 } 64 }
66 return true; 65 return true;
67 } 66 }
68 67
69 bool QuicStreamSequencer::OnStreamFrame(const QuicStreamFrame& frame) { 68 bool QuicStreamSequencer::OnStreamFrame(const QuicStreamFrame& frame) {
70 if (!WillAcceptStreamFrame(frame)) { 69 if (!WillAcceptStreamFrame(frame)) {
71 // This should not happen, as WillAcceptFrame should be called before 70 // This should not happen, as WillAcceptFrame should be called before
72 // OnStreamFrame. Error handling should be done by the caller. 71 // OnStreamFrame. Error handling should be done by the caller.
73 return false; 72 return false;
74 } 73 }
74 if (IsDuplicate(frame)) {
75 // Silently ignore duplicates.
76 return true;
77 }
75 78
76 QuicStreamOffset byte_offset = frame.offset; 79 QuicStreamOffset byte_offset = frame.offset;
77 const char* data = frame.data.data(); 80 const char* data = frame.data.data();
78 size_t data_len = frame.data.size(); 81 size_t data_len = frame.data.size();
79 82
80 if (byte_offset == num_bytes_consumed_) { 83 if (byte_offset == num_bytes_consumed_) {
81 DVLOG(1) << "Processing byte offset " << byte_offset; 84 DVLOG(1) << "Processing byte offset " << byte_offset;
82 size_t bytes_consumed = stream_->ProcessData(data, data_len); 85 size_t bytes_consumed = stream_->ProcessData(data, data_len);
83 num_bytes_consumed_ += bytes_consumed; 86 num_bytes_consumed_ += bytes_consumed;
84 87
85 if (MaybeCloseStream()) { 88 if (MaybeCloseStream()) {
86 return true; 89 return true;
87 } 90 }
88 if (bytes_consumed > data_len) { 91 if (bytes_consumed > data_len) {
89 stream_->Close(QUIC_SERVER_ERROR_PROCESSING_STREAM); 92 stream_->Close(QUIC_SERVER_ERROR_PROCESSING_STREAM);
90 return false; 93 return false;
91 } else if (bytes_consumed == data_len) { 94 } else if (bytes_consumed == data_len) {
92 FlushBufferedFrames(); 95 FlushBufferedFrames();
93 return true; // it's safe to ack this frame. 96 return true; // it's safe to ack this frame.
94 } else { 97 } else {
95 // Set ourselves up to buffer what's left 98 // Set ourselves up to buffer what's left
96 data_len -= bytes_consumed; 99 data_len -= bytes_consumed;
97 data += bytes_consumed; 100 data += bytes_consumed;
98 byte_offset += bytes_consumed; 101 byte_offset += bytes_consumed;
99 } 102 }
100 } 103 }
101
102 DVLOG(1) << "Buffering packet at offset " << byte_offset; 104 DVLOG(1) << "Buffering packet at offset " << byte_offset;
103 frames_.insert(make_pair(byte_offset, string(data, data_len))); 105 frames_.insert(make_pair(byte_offset, string(data, data_len)));
104 return true; 106 return true;
105 } 107 }
106 108
107 void QuicStreamSequencer::CloseStreamAtOffset(QuicStreamOffset offset, 109 void QuicStreamSequencer::CloseStreamAtOffset(QuicStreamOffset offset,
108 bool half_close) { 110 bool half_close) {
109 const QuicStreamOffset kMaxOffset = numeric_limits<QuicStreamOffset>::max(); 111 const QuicStreamOffset kMaxOffset = numeric_limits<QuicStreamOffset>::max();
110 112
111 // If we have a scheduled termination or close, any new offset should match 113 // If we have a scheduled termination or close, any new offset should match
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 } 146 }
145 147
146 bool QuicStreamSequencer::IsHalfClosed() const { 148 bool QuicStreamSequencer::IsHalfClosed() const {
147 return num_bytes_consumed_ >= close_offset_; 149 return num_bytes_consumed_ >= close_offset_;
148 } 150 }
149 151
150 bool QuicStreamSequencer::IsClosed() const { 152 bool QuicStreamSequencer::IsClosed() const {
151 return num_bytes_consumed_ >= close_offset_ && half_close_ == false; 153 return num_bytes_consumed_ >= close_offset_ && half_close_ == false;
152 } 154 }
153 155
156 bool QuicStreamSequencer::IsDuplicate(const QuicStreamFrame& frame) const {
157 // A frame is duplicate if the frame offset is smaller than our bytes consumed
158 // or we have stored the frame in our map.
159 // TODO(pwestin): Is it possible that a new frame contain more data even if
160 // the offset is the same?
161 return (frame.offset < num_bytes_consumed_ ||
162 frames_.find(frame.offset) != frames_.end());
163 }
164
154 void QuicStreamSequencer::FlushBufferedFrames() { 165 void QuicStreamSequencer::FlushBufferedFrames() {
155 FrameMap::iterator it = frames_.find(num_bytes_consumed_); 166 FrameMap::iterator it = frames_.find(num_bytes_consumed_);
156 while (it != frames_.end()) { 167 while (it != frames_.end()) {
157 DVLOG(1) << "Flushing buffered packet at offset " << it->first; 168 DVLOG(1) << "Flushing buffered packet at offset " << it->first;
158 string* data = &it->second; 169 string* data = &it->second;
159 size_t bytes_consumed = stream_->ProcessData(data->c_str(), data->size()); 170 size_t bytes_consumed = stream_->ProcessData(data->c_str(), data->size());
160 num_bytes_consumed_ += bytes_consumed; 171 num_bytes_consumed_ += bytes_consumed;
161 if (MaybeCloseStream()) { 172 if (MaybeCloseStream()) {
162 return; 173 return;
163 } 174 }
164 if (bytes_consumed > data->size()) { 175 if (bytes_consumed > data->size()) {
165 stream_->Close(QUIC_SERVER_ERROR_PROCESSING_STREAM); // Programming error 176 stream_->Close(QUIC_SERVER_ERROR_PROCESSING_STREAM); // Programming error
166 return; 177 return;
167 } else if (bytes_consumed == data->size()) { 178 } else if (bytes_consumed == data->size()) {
168 frames_.erase(it); 179 frames_.erase(it);
169 it = frames_.find(num_bytes_consumed_); 180 it = frames_.find(num_bytes_consumed_);
170 } else { 181 } else {
171 string new_data = it->second.substr(bytes_consumed); 182 string new_data = it->second.substr(bytes_consumed);
172 frames_.erase(it); 183 frames_.erase(it);
173 frames_.insert(make_pair(num_bytes_consumed_, new_data)); 184 frames_.insert(make_pair(num_bytes_consumed_, new_data));
174 return; 185 return;
175 } 186 }
176 } 187 }
177 } 188 }
178 189
179 } // namespace net 190 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_stream_sequencer.h ('k') | net/quic/quic_stream_sequencer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698