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

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

Issue 14651009: Land Recent QUIC changes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix integer constant is too large for 'unsigned long' type 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
« 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 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_->ProcessData(data, data_len); 85 size_t bytes_consumed = stream_->ProcessRawData(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
142 bool QuicStreamSequencer::HasBytesToRead() const { 223 bool QuicStreamSequencer::HasBytesToRead() const {
143 FrameMap::const_iterator it = frames_.begin(); 224 FrameMap::const_iterator it = frames_.begin();
144 225
145 return it != frames_.end() && it->first == num_bytes_consumed_; 226 return it != frames_.end() && it->first == num_bytes_consumed_;
146 } 227 }
147 228
148 bool QuicStreamSequencer::IsHalfClosed() const { 229 bool QuicStreamSequencer::IsHalfClosed() const {
149 return num_bytes_consumed_ >= close_offset_; 230 return num_bytes_consumed_ >= close_offset_;
150 } 231 }
151 232
152 bool QuicStreamSequencer::IsClosed() const { 233 bool QuicStreamSequencer::IsClosed() const {
153 return num_bytes_consumed_ >= close_offset_ && half_close_ == false; 234 return num_bytes_consumed_ >= close_offset_ && half_close_ == false;
154 } 235 }
155 236
156 bool QuicStreamSequencer::IsDuplicate(const QuicStreamFrame& frame) const { 237 bool QuicStreamSequencer::IsDuplicate(const QuicStreamFrame& frame) const {
157 // A frame is duplicate if the frame offset is smaller than our bytes consumed 238 // A frame is duplicate if the frame offset is smaller than our bytes consumed
158 // or we have stored the frame in our map. 239 // or we have stored the frame in our map.
159 // TODO(pwestin): Is it possible that a new frame contain more data even if 240 // TODO(pwestin): Is it possible that a new frame contain more data even if
160 // the offset is the same? 241 // the offset is the same?
161 return frame.offset < num_bytes_consumed_ || 242 return frame.offset < num_bytes_consumed_ ||
162 frames_.find(frame.offset) != frames_.end(); 243 frames_.find(frame.offset) != frames_.end();
163 } 244 }
164 245
165 void QuicStreamSequencer::FlushBufferedFrames() { 246 void QuicStreamSequencer::FlushBufferedFrames() {
166 FrameMap::iterator it = frames_.find(num_bytes_consumed_); 247 FrameMap::iterator it = frames_.find(num_bytes_consumed_);
167 while (it != frames_.end()) { 248 while (it != frames_.end()) {
168 DVLOG(1) << "Flushing buffered packet at offset " << it->first; 249 DVLOG(1) << "Flushing buffered packet at offset " << it->first;
169 string* data = &it->second; 250 string* data = &it->second;
170 size_t bytes_consumed = stream_->ProcessData(data->c_str(), data->size()); 251 size_t bytes_consumed = stream_->ProcessRawData(data->c_str(),
252 data->size());
171 num_bytes_consumed_ += bytes_consumed; 253 num_bytes_consumed_ += bytes_consumed;
172 if (MaybeCloseStream()) { 254 if (MaybeCloseStream()) {
173 return; 255 return;
174 } 256 }
175 if (bytes_consumed > data->size()) { 257 if (bytes_consumed > data->size()) {
176 stream_->Close(QUIC_SERVER_ERROR_PROCESSING_STREAM); // Programming error 258 stream_->Close(QUIC_SERVER_ERROR_PROCESSING_STREAM); // Programming error
177 return; 259 return;
178 } else if (bytes_consumed == data->size()) { 260 } else if (bytes_consumed == data->size()) {
179 frames_.erase(it); 261 frames_.erase(it);
180 it = frames_.find(num_bytes_consumed_); 262 it = frames_.find(num_bytes_consumed_);
181 } else { 263 } else {
182 string new_data = it->second.substr(bytes_consumed); 264 string new_data = it->second.substr(bytes_consumed);
183 frames_.erase(it); 265 frames_.erase(it);
184 frames_.insert(make_pair(num_bytes_consumed_, new_data)); 266 frames_.insert(make_pair(num_bytes_consumed_, new_data));
185 return; 267 return;
186 } 268 }
187 } 269 }
188 } 270 }
189 271
190 } // namespace net 272 } // 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