| 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 |