| OLD | NEW |
| 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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 if (!WillAcceptStreamFrame(frame)) { | 67 if (!WillAcceptStreamFrame(frame)) { |
| 68 // This should not happen, as WillAcceptFrame should be called before | 68 // This should not happen, as WillAcceptFrame should be called before |
| 69 // OnStreamFrame. Error handling should be done by the caller. | 69 // OnStreamFrame. Error handling should be done by the caller. |
| 70 return false; | 70 return false; |
| 71 } | 71 } |
| 72 if (IsDuplicate(frame)) { | 72 if (IsDuplicate(frame)) { |
| 73 // Silently ignore duplicates. | 73 // Silently ignore duplicates. |
| 74 return true; | 74 return true; |
| 75 } | 75 } |
| 76 | 76 |
| 77 if (frame.fin) { | |
| 78 CloseStreamAtOffset(frame.offset + frame.data.size()); | |
| 79 } | |
| 80 | |
| 81 QuicStreamOffset byte_offset = frame.offset; | 77 QuicStreamOffset byte_offset = frame.offset; |
| 82 const char* data = frame.data.data(); | 78 const char* data = frame.data.data(); |
| 83 size_t data_len = frame.data.size(); | 79 size_t data_len = frame.data.size(); |
| 84 | 80 |
| 85 if (data_len == 0) { | 81 if (data_len == 0 && !frame.fin) { |
| 86 // TODO(rch): Close the stream if there was no data and no fin. | 82 // Stream frames must have data or a fin flag. |
| 87 return true; | 83 stream_->ConnectionClose(QUIC_INVALID_STREAM_FRAME, false); |
| 84 return false; |
| 85 } |
| 86 |
| 87 if (frame.fin) { |
| 88 CloseStreamAtOffset(frame.offset + frame.data.size()); |
| 89 if (data_len == 0) { |
| 90 return true; |
| 91 } |
| 88 } | 92 } |
| 89 | 93 |
| 90 if (byte_offset == num_bytes_consumed_) { | 94 if (byte_offset == num_bytes_consumed_) { |
| 91 DVLOG(1) << "Processing byte offset " << byte_offset; | 95 DVLOG(1) << "Processing byte offset " << byte_offset; |
| 92 size_t bytes_consumed = stream_->ProcessRawData(data, data_len); | 96 size_t bytes_consumed = stream_->ProcessRawData(data, data_len); |
| 93 num_bytes_consumed_ += bytes_consumed; | 97 num_bytes_consumed_ += bytes_consumed; |
| 94 | 98 |
| 95 if (MaybeCloseStream()) { | 99 if (MaybeCloseStream()) { |
| 96 return true; | 100 return true; |
| 97 } | 101 } |
| 98 if (bytes_consumed > data_len) { | 102 if (bytes_consumed > data_len) { |
| 99 stream_->Close(QUIC_SERVER_ERROR_PROCESSING_STREAM); | 103 stream_->Close(QUIC_ERROR_PROCESSING_STREAM); |
| 100 return false; | 104 return false; |
| 101 } else if (bytes_consumed == data_len) { | 105 } else if (bytes_consumed == data_len) { |
| 102 FlushBufferedFrames(); | 106 FlushBufferedFrames(); |
| 103 return true; // it's safe to ack this frame. | 107 return true; // it's safe to ack this frame. |
| 104 } else { | 108 } else { |
| 105 // Set ourselves up to buffer what's left | 109 // Set ourselves up to buffer what's left |
| 106 data_len -= bytes_consumed; | 110 data_len -= bytes_consumed; |
| 107 data += bytes_consumed; | 111 data += bytes_consumed; |
| 108 byte_offset += bytes_consumed; | 112 byte_offset += bytes_consumed; |
| 109 } | 113 } |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 void QuicStreamSequencer::MarkConsumed(size_t num_bytes_consumed) { | 208 void QuicStreamSequencer::MarkConsumed(size_t num_bytes_consumed) { |
| 205 size_t end_offset = num_bytes_consumed_ + num_bytes_consumed; | 209 size_t end_offset = num_bytes_consumed_ + num_bytes_consumed; |
| 206 while (!frames_.empty() && end_offset != num_bytes_consumed_) { | 210 while (!frames_.empty() && end_offset != num_bytes_consumed_) { |
| 207 FrameMap::iterator it = frames_.begin(); | 211 FrameMap::iterator it = frames_.begin(); |
| 208 if (it->first != num_bytes_consumed_) { | 212 if (it->first != num_bytes_consumed_) { |
| 209 LOG(DFATAL) << "Invalid argument to MarkConsumed. " | 213 LOG(DFATAL) << "Invalid argument to MarkConsumed. " |
| 210 << " num_bytes_consumed_: " << num_bytes_consumed_ | 214 << " num_bytes_consumed_: " << num_bytes_consumed_ |
| 211 << " end_offset: " << end_offset | 215 << " end_offset: " << end_offset |
| 212 << " offset: " << it->first | 216 << " offset: " << it->first |
| 213 << " length: " << it->second.length(); | 217 << " length: " << it->second.length(); |
| 214 stream_->Close(QUIC_SERVER_ERROR_PROCESSING_STREAM); | 218 stream_->Close(QUIC_ERROR_PROCESSING_STREAM); |
| 215 return; | 219 return; |
| 216 } | 220 } |
| 217 | 221 |
| 218 if (it->first + it->second.length() <= end_offset) { | 222 if (it->first + it->second.length() <= end_offset) { |
| 219 num_bytes_consumed_ += it->second.length(); | 223 num_bytes_consumed_ += it->second.length(); |
| 220 // This chunk is entirely consumed. | 224 // This chunk is entirely consumed. |
| 221 frames_.erase(it); | 225 frames_.erase(it); |
| 222 continue; | 226 continue; |
| 223 } | 227 } |
| 224 | 228 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 255 while (it != frames_.end()) { | 259 while (it != frames_.end()) { |
| 256 DVLOG(1) << "Flushing buffered packet at offset " << it->first; | 260 DVLOG(1) << "Flushing buffered packet at offset " << it->first; |
| 257 string* data = &it->second; | 261 string* data = &it->second; |
| 258 size_t bytes_consumed = stream_->ProcessRawData(data->c_str(), | 262 size_t bytes_consumed = stream_->ProcessRawData(data->c_str(), |
| 259 data->size()); | 263 data->size()); |
| 260 num_bytes_consumed_ += bytes_consumed; | 264 num_bytes_consumed_ += bytes_consumed; |
| 261 if (MaybeCloseStream()) { | 265 if (MaybeCloseStream()) { |
| 262 return; | 266 return; |
| 263 } | 267 } |
| 264 if (bytes_consumed > data->size()) { | 268 if (bytes_consumed > data->size()) { |
| 265 stream_->Close(QUIC_SERVER_ERROR_PROCESSING_STREAM); // Programming error | 269 stream_->Close(QUIC_ERROR_PROCESSING_STREAM); // Programming error |
| 266 return; | 270 return; |
| 267 } else if (bytes_consumed == data->size()) { | 271 } else if (bytes_consumed == data->size()) { |
| 268 frames_.erase(it); | 272 frames_.erase(it); |
| 269 it = frames_.find(num_bytes_consumed_); | 273 it = frames_.find(num_bytes_consumed_); |
| 270 } else { | 274 } else { |
| 271 string new_data = it->second.substr(bytes_consumed); | 275 string new_data = it->second.substr(bytes_consumed); |
| 272 frames_.erase(it); | 276 frames_.erase(it); |
| 273 frames_.insert(make_pair(num_bytes_consumed_, new_data)); | 277 frames_.insert(make_pair(num_bytes_consumed_, new_data)); |
| 274 return; | 278 return; |
| 275 } | 279 } |
| 276 } | 280 } |
| 277 } | 281 } |
| 278 | 282 |
| 279 } // namespace net | 283 } // namespace net |
| OLD | NEW |