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

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

Issue 320263003: Connection level flow control (CLFC) accounting on receipt of FIN/RST (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 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_session.h ('k') | net/quic/quic_session_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_session.h" 5 #include "net/quic/quic_session.h"
6 6
7 #include "base/stl_util.h" 7 #include "base/stl_util.h"
8 #include "net/quic/crypto/proof_verifier.h" 8 #include "net/quic/crypto/proof_verifier.h"
9 #include "net/quic/quic_connection.h" 9 #include "net/quic/quic_connection.h"
10 #include "net/quic/quic_flags.h" 10 #include "net/quic/quic_flags.h"
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 // For version above QUIC v12, the headers stream is stream 3, so the 133 // For version above QUIC v12, the headers stream is stream 3, so the
134 // next available local stream ID should be 5. 134 // next available local stream ID should be 5.
135 DCHECK_EQ(kHeadersStreamId, next_stream_id_); 135 DCHECK_EQ(kHeadersStreamId, next_stream_id_);
136 next_stream_id_ += 2; 136 next_stream_id_ += 2;
137 } 137 }
138 } 138 }
139 139
140 QuicSession::~QuicSession() { 140 QuicSession::~QuicSession() {
141 STLDeleteElements(&closed_streams_); 141 STLDeleteElements(&closed_streams_);
142 STLDeleteValues(&stream_map_); 142 STLDeleteValues(&stream_map_);
143
144 DLOG_IF(WARNING,
145 locally_closed_streams_highest_offset_.size() > max_open_streams_)
146 << "Surprisingly high number of locally closed streams still waiting for "
147 "final byte offset: " << locally_closed_streams_highest_offset_.size();
143 } 148 }
144 149
145 void QuicSession::OnStreamFrames(const vector<QuicStreamFrame>& frames) { 150 void QuicSession::OnStreamFrames(const vector<QuicStreamFrame>& frames) {
146 for (size_t i = 0; i < frames.size(); ++i) { 151 for (size_t i = 0; i < frames.size(); ++i) {
147 // TODO(rch) deal with the error case of stream id 0. 152 // TODO(rch) deal with the error case of stream id 0.
148 QuicStreamId stream_id = frames[i].stream_id; 153 const QuicStreamFrame& frame = frames[i];
154 QuicStreamId stream_id = frame.stream_id;
149 ReliableQuicStream* stream = GetStream(stream_id); 155 ReliableQuicStream* stream = GetStream(stream_id);
150 if (!stream) { 156 if (!stream) {
157 // The stream no longer exists, but we may still be interested in the
158 // final stream byte offset sent by the peer. A frame with a FIN can give
159 // us this offset.
160 if (frame.fin) {
161 QuicStreamOffset final_byte_offset =
162 frame.offset + frame.data.TotalBufferSize();
163 UpdateFlowControlOnFinalReceivedByteOffset(stream_id,
164 final_byte_offset);
165 }
166
151 continue; 167 continue;
152 } 168 }
153 stream->OnStreamFrame(frames[i]); 169 stream->OnStreamFrame(frames[i]);
154 } 170 }
155 } 171 }
156 172
157 void QuicSession::OnStreamHeaders(QuicStreamId stream_id, 173 void QuicSession::OnStreamHeaders(QuicStreamId stream_id,
158 StringPiece headers_data) { 174 StringPiece headers_data) {
159 QuicDataStream* stream = GetDataStream(stream_id); 175 QuicDataStream* stream = GetDataStream(stream_id);
160 if (!stream) { 176 if (!stream) {
(...skipping 30 matching lines...) Expand all
191 QUIC_INVALID_STREAM_ID, 207 QUIC_INVALID_STREAM_ID,
192 "Attempt to reset the crypto stream"); 208 "Attempt to reset the crypto stream");
193 return; 209 return;
194 } 210 }
195 if (frame.stream_id == kHeadersStreamId) { 211 if (frame.stream_id == kHeadersStreamId) {
196 connection()->SendConnectionCloseWithDetails( 212 connection()->SendConnectionCloseWithDetails(
197 QUIC_INVALID_STREAM_ID, 213 QUIC_INVALID_STREAM_ID,
198 "Attempt to reset the headers stream"); 214 "Attempt to reset the headers stream");
199 return; 215 return;
200 } 216 }
217
201 QuicDataStream* stream = GetDataStream(frame.stream_id); 218 QuicDataStream* stream = GetDataStream(frame.stream_id);
202 if (!stream) { 219 if (!stream) {
220 // The RST frame contains the final byte offset for the stream: we can now
221 // update the connection level flow controller if needed.
222 UpdateFlowControlOnFinalReceivedByteOffset(frame.stream_id,
223 frame.byte_offset);
203 return; // Errors are handled by GetStream. 224 return; // Errors are handled by GetStream.
204 } 225 }
205 226
206 stream->OnStreamReset(frame); 227 stream->OnStreamReset(frame);
207 } 228 }
208 229
209 void QuicSession::OnGoAway(const QuicGoAwayFrame& frame) { 230 void QuicSession::OnGoAway(const QuicGoAwayFrame& frame) {
210 DCHECK(frame.last_good_stream_id < next_stream_id_); 231 DCHECK(frame.last_good_stream_id < next_stream_id_);
211 goaway_received_ = true; 232 goaway_received_ = true;
212 } 233 }
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 return; 410 return;
390 } 411 }
391 QuicDataStream* stream = it->second; 412 QuicDataStream* stream = it->second;
392 413
393 // Tell the stream that a RST has been sent. 414 // Tell the stream that a RST has been sent.
394 if (locally_reset) { 415 if (locally_reset) {
395 stream->set_rst_sent(true); 416 stream->set_rst_sent(true);
396 } 417 }
397 418
398 closed_streams_.push_back(it->second); 419 closed_streams_.push_back(it->second);
420
421 // If we haven't received a FIN or RST for this stream, we need to keep track
422 // of the how many bytes the stream's flow controller believes it has
423 // received, for accurate connection level flow control accounting.
424 if (!stream->HasFinalReceivedByteOffset() &&
425 stream->flow_controller()->IsEnabled() &&
426 FLAGS_enable_quic_connection_flow_control) {
427 locally_closed_streams_highest_offset_[stream_id] =
428 stream->flow_controller()->highest_received_byte_offset();
429 }
430
399 stream_map_.erase(it); 431 stream_map_.erase(it);
400 stream->OnClose(); 432 stream->OnClose();
401 } 433 }
402 434
435 void QuicSession::UpdateFlowControlOnFinalReceivedByteOffset(
436 QuicStreamId stream_id, QuicStreamOffset final_byte_offset) {
437 if (!FLAGS_enable_quic_connection_flow_control) {
438 return;
439 }
440
441 map<QuicStreamId, QuicStreamOffset>::iterator it =
442 locally_closed_streams_highest_offset_.find(stream_id);
443 if (it == locally_closed_streams_highest_offset_.end()) {
444 return;
445 }
446
447 DVLOG(1) << ENDPOINT << "Received final byte offset " << final_byte_offset
448 << " for stream " << stream_id;
449 uint64 offset_diff = final_byte_offset - it->second;
450 if (flow_controller_->UpdateHighestReceivedOffset(
451 flow_controller_->highest_received_byte_offset() + offset_diff)) {
452 // If the final offset violates flow control, close the connection now.
453 if (flow_controller_->FlowControlViolation()) {
454 connection_->SendConnectionClose(QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA);
455 return;
456 }
457 }
458
459 flow_controller_->AddBytesConsumed(offset_diff);
460 locally_closed_streams_highest_offset_.erase(it);
461 }
462
403 bool QuicSession::IsEncryptionEstablished() { 463 bool QuicSession::IsEncryptionEstablished() {
404 return GetCryptoStream()->encryption_established(); 464 return GetCryptoStream()->encryption_established();
405 } 465 }
406 466
407 bool QuicSession::IsCryptoHandshakeConfirmed() { 467 bool QuicSession::IsCryptoHandshakeConfirmed() {
408 return GetCryptoStream()->handshake_confirmed(); 468 return GetCryptoStream()->handshake_confirmed();
409 } 469 }
410 470
411 void QuicSession::OnConfigNegotiated() { 471 void QuicSession::OnConfigNegotiated() {
412 connection_->SetFromConfig(config_); 472 connection_->SetFromConfig(config_);
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 // with a different version. 708 // with a different version.
649 for (DataStreamMap::iterator it = stream_map_.begin(); 709 for (DataStreamMap::iterator it = stream_map_.begin();
650 it != stream_map_.end(); ++it) { 710 it != stream_map_.end(); ++it) {
651 if (version < QUIC_VERSION_17) { 711 if (version < QUIC_VERSION_17) {
652 it->second->flow_controller()->Disable(); 712 it->second->flow_controller()->Disable();
653 } 713 }
654 } 714 }
655 } 715 }
656 716
657 } // namespace net 717 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_session.h ('k') | net/quic/quic_session_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698