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

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

Issue 15018013: Revert 198736 "Land Recent QUIC changes" (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 7 years, 7 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
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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 // Silently ignore duplicates. 75 // Silently ignore duplicates.
76 return true; 76 return true;
77 } 77 }
78 78
79 QuicStreamOffset byte_offset = frame.offset; 79 QuicStreamOffset byte_offset = frame.offset;
80 const char* data = frame.data.data(); 80 const char* data = frame.data.data();
81 size_t data_len = frame.data.size(); 81 size_t data_len = frame.data.size();
82 82
83 if (byte_offset == num_bytes_consumed_) { 83 if (byte_offset == num_bytes_consumed_) {
84 DVLOG(1) << "Processing byte offset " << byte_offset; 84 DVLOG(1) << "Processing byte offset " << byte_offset;
85 size_t bytes_consumed = stream_->ProcessRawData(data, data_len); 85 size_t bytes_consumed = stream_->ProcessData(data, data_len);
86 num_bytes_consumed_ += bytes_consumed; 86 num_bytes_consumed_ += bytes_consumed;
87 87
88 if (MaybeCloseStream()) { 88 if (MaybeCloseStream()) {
89 return true; 89 return true;
90 } 90 }
91 if (bytes_consumed > data_len) { 91 if (bytes_consumed > data_len) {
92 stream_->Close(QUIC_SERVER_ERROR_PROCESSING_STREAM); 92 stream_->Close(QUIC_SERVER_ERROR_PROCESSING_STREAM);
93 return false; 93 return false;
94 } else if (bytes_consumed == data_len) { 94 } else if (bytes_consumed == data_len) {
95 FlushBufferedFrames(); 95 FlushBufferedFrames();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 << num_bytes_consumed_ << " of " << close_offset_ 132 << num_bytes_consumed_ << " of " << close_offset_
133 << " bytes."; 133 << " bytes.";
134 // Technically it's an error if num_bytes_consumed isn't exactly 134 // Technically it's an error if num_bytes_consumed isn't exactly
135 // equal, but error handling seems silly at this point. 135 // equal, but error handling seems silly at this point.
136 stream_->TerminateFromPeer(half_close_); 136 stream_->TerminateFromPeer(half_close_);
137 return true; 137 return true;
138 } 138 }
139 return false; 139 return false;
140 } 140 }
141 141
142 int QuicStreamSequencer::GetReadableRegions(iovec* iov, int iov_len) {
143 FrameMap::iterator it = frames_.begin();
144 int index = 0;
145 uint64 offset = num_bytes_consumed_;
146 while (it != frames_.end() && index < iov_len) {
147 if (it->first != offset) return index;
148
149 iov[index].iov_base = static_cast<void*>(
150 const_cast<char*>(it->second.data()));
151 iov[index].iov_len = it->second.size();
152 offset += it->second.size();
153
154 ++index;
155 ++it;
156 }
157 return index;
158 }
159
160 int QuicStreamSequencer::Readv(const struct iovec* iov, int iov_len) {
161 FrameMap::iterator it = frames_.begin();
162 int iov_index = 0;
163 size_t iov_offset = 0;
164 size_t frame_offset = 0;
165 size_t initial_bytes_consumed = num_bytes_consumed_;
166
167 while (iov_index < iov_len &&
168 it != frames_.end() &&
169 it->first == num_bytes_consumed_) {
170 int bytes_to_read = min(iov[iov_index].iov_len - iov_offset,
171 it->second.size() - frame_offset);
172
173 char* iov_ptr = static_cast<char*>(iov[iov_index].iov_base) + iov_offset;
174 memcpy(iov_ptr,
175 it->second.data() + frame_offset, bytes_to_read);
176 frame_offset += bytes_to_read;
177 iov_offset += bytes_to_read;
178
179 if (iov[iov_index].iov_len == iov_offset) {
180 // We've filled this buffer.
181 iov_offset = 0;
182 ++iov_index;
183 }
184 if (it->second.size() == frame_offset) {
185 // We've copied this whole frame
186 num_bytes_consumed_ += it->second.size();
187 frames_.erase(it);
188 it = frames_.begin();
189 frame_offset = 0;
190 }
191 }
192 // We've finished copying. If we have a partial frame, update it.
193 if (frame_offset != 0) {
194 frames_.insert(make_pair(it->first + frame_offset,
195 it->second.substr(frame_offset)));
196 frames_.erase(frames_.begin());
197 num_bytes_consumed_ += frame_offset;
198 }
199 return num_bytes_consumed_ - initial_bytes_consumed;
200 }
201
202 void QuicStreamSequencer::MarkConsumed(size_t num_bytes_consumed) {
203 size_t end_offset = num_bytes_consumed_ + num_bytes_consumed;
204 while (!frames_.empty()) {
205 FrameMap::iterator it = frames_.begin();
206 if (it->first + it->second.length() <= end_offset) {
207 // This chunk is entirely consumed.
208 frames_.erase(it);
209 continue;
210 }
211
212 if (it->first != end_offset) {
213 // Partially consume this frame.
214 frames_.insert(make_pair(end_offset,
215 it->second.substr(end_offset - it->first)));
216 frames_.erase(it);
217 }
218 break;
219 }
220 num_bytes_consumed_ = end_offset;
221 }
222
223 bool QuicStreamSequencer::HasBytesToRead() const { 142 bool QuicStreamSequencer::HasBytesToRead() const {
224 FrameMap::const_iterator it = frames_.begin(); 143 FrameMap::const_iterator it = frames_.begin();
225 144
226 return it != frames_.end() && it->first == num_bytes_consumed_; 145 return it != frames_.end() && it->first == num_bytes_consumed_;
227 } 146 }
228 147
229 bool QuicStreamSequencer::IsHalfClosed() const { 148 bool QuicStreamSequencer::IsHalfClosed() const {
230 return num_bytes_consumed_ >= close_offset_; 149 return num_bytes_consumed_ >= close_offset_;
231 } 150 }
232 151
233 bool QuicStreamSequencer::IsClosed() const { 152 bool QuicStreamSequencer::IsClosed() const {
234 return num_bytes_consumed_ >= close_offset_ && half_close_ == false; 153 return num_bytes_consumed_ >= close_offset_ && half_close_ == false;
235 } 154 }
236 155
237 bool QuicStreamSequencer::IsDuplicate(const QuicStreamFrame& frame) const { 156 bool QuicStreamSequencer::IsDuplicate(const QuicStreamFrame& frame) const {
238 // A frame is duplicate if the frame offset is smaller than our bytes consumed 157 // A frame is duplicate if the frame offset is smaller than our bytes consumed
239 // or we have stored the frame in our map. 158 // or we have stored the frame in our map.
240 // TODO(pwestin): Is it possible that a new frame contain more data even if 159 // TODO(pwestin): Is it possible that a new frame contain more data even if
241 // the offset is the same? 160 // the offset is the same?
242 return frame.offset < num_bytes_consumed_ || 161 return frame.offset < num_bytes_consumed_ ||
243 frames_.find(frame.offset) != frames_.end(); 162 frames_.find(frame.offset) != frames_.end();
244 } 163 }
245 164
246 void QuicStreamSequencer::FlushBufferedFrames() { 165 void QuicStreamSequencer::FlushBufferedFrames() {
247 FrameMap::iterator it = frames_.find(num_bytes_consumed_); 166 FrameMap::iterator it = frames_.find(num_bytes_consumed_);
248 while (it != frames_.end()) { 167 while (it != frames_.end()) {
249 DVLOG(1) << "Flushing buffered packet at offset " << it->first; 168 DVLOG(1) << "Flushing buffered packet at offset " << it->first;
250 string* data = &it->second; 169 string* data = &it->second;
251 size_t bytes_consumed = stream_->ProcessRawData(data->c_str(), 170 size_t bytes_consumed = stream_->ProcessData(data->c_str(), data->size());
252 data->size());
253 num_bytes_consumed_ += bytes_consumed; 171 num_bytes_consumed_ += bytes_consumed;
254 if (MaybeCloseStream()) { 172 if (MaybeCloseStream()) {
255 return; 173 return;
256 } 174 }
257 if (bytes_consumed > data->size()) { 175 if (bytes_consumed > data->size()) {
258 stream_->Close(QUIC_SERVER_ERROR_PROCESSING_STREAM); // Programming error 176 stream_->Close(QUIC_SERVER_ERROR_PROCESSING_STREAM); // Programming error
259 return; 177 return;
260 } else if (bytes_consumed == data->size()) { 178 } else if (bytes_consumed == data->size()) {
261 frames_.erase(it); 179 frames_.erase(it);
262 it = frames_.find(num_bytes_consumed_); 180 it = frames_.find(num_bytes_consumed_);
263 } else { 181 } else {
264 string new_data = it->second.substr(bytes_consumed); 182 string new_data = it->second.substr(bytes_consumed);
265 frames_.erase(it); 183 frames_.erase(it);
266 frames_.insert(make_pair(num_bytes_consumed_, new_data)); 184 frames_.insert(make_pair(num_bytes_consumed_, new_data));
267 return; 185 return;
268 } 186 }
269 } 187 }
270 } 188 }
271 189
272 } // namespace net 190 } // namespace net
OLDNEW
« no previous file with comments | « trunk/src/net/quic/quic_stream_sequencer.h ('k') | trunk/src/net/quic/quic_stream_sequencer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698