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_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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |