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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 max_open_streams_(config_.MaxStreamsPerConnection()), | 106 max_open_streams_(config_.MaxStreamsPerConnection()), |
107 next_outgoing_stream_id_(perspective() == Perspective::IS_SERVER ? 2 : 3), | 107 next_outgoing_stream_id_(perspective() == Perspective::IS_SERVER ? 2 : 3), |
108 largest_peer_created_stream_id_( | 108 largest_peer_created_stream_id_( |
109 perspective() == Perspective::IS_SERVER ? 1 : 0), | 109 perspective() == Perspective::IS_SERVER ? 1 : 0), |
110 error_(QUIC_NO_ERROR), | 110 error_(QUIC_NO_ERROR), |
111 flow_controller_(connection_.get(), | 111 flow_controller_(connection_.get(), |
112 0, | 112 0, |
113 perspective(), | 113 perspective(), |
114 kMinimumFlowControlSendWindow, | 114 kMinimumFlowControlSendWindow, |
115 config_.GetInitialSessionFlowControlWindowToSend(), | 115 config_.GetInitialSessionFlowControlWindowToSend(), |
116 false), | 116 false) {} |
117 has_pending_handshake_(false) {} | |
118 | 117 |
119 void QuicSession::Initialize() { | 118 void QuicSession::Initialize() { |
120 connection_->set_visitor(visitor_shim_.get()); | 119 connection_->set_visitor(visitor_shim_.get()); |
121 connection_->SetFromConfig(config_); | 120 connection_->SetFromConfig(config_); |
122 | 121 |
123 DCHECK_EQ(kCryptoStreamId, GetCryptoStream()->id()); | 122 DCHECK_EQ(kCryptoStreamId, GetCryptoStream()->id()); |
124 static_stream_map_[kCryptoStreamId] = GetCryptoStream(); | 123 static_stream_map_[kCryptoStreamId] = GetCryptoStream(); |
125 } | 124 } |
126 | 125 |
127 QuicSession::~QuicSession() { | 126 QuicSession::~QuicSession() { |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 write_blocked_streams_.HasWriteBlockedDataStreams())) { | 251 write_blocked_streams_.HasWriteBlockedDataStreams())) { |
253 // Writing one stream removed another!? Something's broken. | 252 // Writing one stream removed another!? Something's broken. |
254 LOG(DFATAL) << "WriteBlockedStream is missing"; | 253 LOG(DFATAL) << "WriteBlockedStream is missing"; |
255 connection_->CloseConnection(QUIC_INTERNAL_ERROR, false); | 254 connection_->CloseConnection(QUIC_INTERNAL_ERROR, false); |
256 return; | 255 return; |
257 } | 256 } |
258 if (!connection_->CanWriteStreamData()) { | 257 if (!connection_->CanWriteStreamData()) { |
259 return; | 258 return; |
260 } | 259 } |
261 QuicStreamId stream_id = write_blocked_streams_.PopFront(); | 260 QuicStreamId stream_id = write_blocked_streams_.PopFront(); |
262 if (stream_id == kCryptoStreamId) { | |
263 has_pending_handshake_ = false; // We just popped it. | |
264 } | |
265 ReliableQuicStream* stream = GetStream(stream_id); | 261 ReliableQuicStream* stream = GetStream(stream_id); |
266 if (stream != nullptr && !stream->flow_controller()->IsBlocked()) { | 262 if (stream != nullptr && !stream->flow_controller()->IsBlocked()) { |
267 // If the stream can't write all bytes it'll re-add itself to the blocked | 263 // If the stream can't write all bytes it'll re-add itself to the blocked |
268 // list. | 264 // list. |
269 stream->OnCanWrite(); | 265 stream->OnCanWrite(); |
270 } | 266 } |
271 } | 267 } |
272 } | 268 } |
273 | 269 |
274 bool QuicSession::WillingAndAbleToWrite() const { | 270 bool QuicSession::WillingAndAbleToWrite() const { |
275 // If the crypto or headers streams are blocked, we want to schedule a write - | 271 // If the crypto or headers streams are blocked, we want to schedule a write - |
276 // they don't get blocked by connection level flow control. Otherwise only | 272 // they don't get blocked by connection level flow control. Otherwise only |
277 // schedule a write if we are not flow control blocked at the connection | 273 // schedule a write if we are not flow control blocked at the connection |
278 // level. | 274 // level. |
279 return write_blocked_streams_.HasWriteBlockedCryptoOrHeadersStream() || | 275 return write_blocked_streams_.HasWriteBlockedCryptoOrHeadersStream() || |
280 (!flow_controller_.IsBlocked() && | 276 (!flow_controller_.IsBlocked() && |
281 write_blocked_streams_.HasWriteBlockedDataStreams()); | 277 write_blocked_streams_.HasWriteBlockedDataStreams()); |
282 } | 278 } |
283 | 279 |
284 bool QuicSession::HasPendingHandshake() const { | 280 bool QuicSession::HasPendingHandshake() const { |
285 return has_pending_handshake_; | 281 return write_blocked_streams_.crypto_stream_blocked(); |
286 } | 282 } |
287 | 283 |
288 bool QuicSession::HasOpenDynamicStreams() const { | 284 bool QuicSession::HasOpenDynamicStreams() const { |
289 return GetNumOpenStreams() > 0; | 285 return GetNumOpenStreams() > 0; |
290 } | 286 } |
291 | 287 |
292 QuicConsumedData QuicSession::WritevData( | 288 QuicConsumedData QuicSession::WritevData( |
293 QuicStreamId id, | 289 QuicStreamId id, |
294 QuicIOVector iov, | 290 QuicIOVector iov, |
295 QuicStreamOffset offset, | 291 QuicStreamOffset offset, |
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
741 if (stream != nullptr) { | 737 if (stream != nullptr) { |
742 LOG_IF(DFATAL, priority != stream->Priority()) | 738 LOG_IF(DFATAL, priority != stream->Priority()) |
743 << ENDPOINT << "Stream " << id | 739 << ENDPOINT << "Stream " << id |
744 << "Priorities do not match. Got: " << static_cast<int>(priority) | 740 << "Priorities do not match. Got: " << static_cast<int>(priority) |
745 << " Expected: " << static_cast<int>(stream->Priority()); | 741 << " Expected: " << static_cast<int>(stream->Priority()); |
746 } else { | 742 } else { |
747 LOG(DFATAL) << "Marking unknown stream " << id << " blocked."; | 743 LOG(DFATAL) << "Marking unknown stream " << id << " blocked."; |
748 } | 744 } |
749 #endif | 745 #endif |
750 | 746 |
751 if (id == kCryptoStreamId) { | |
752 DCHECK(!has_pending_handshake_); | |
753 has_pending_handshake_ = true; | |
754 // TODO(jar): Be sure to use the highest priority for the crypto stream, | |
755 // perhaps by adding a "special" priority for it that is higher than | |
756 // kHighestPriority. | |
757 priority = kHighestPriority; | |
758 } | |
759 write_blocked_streams_.AddStream(id, priority); | 747 write_blocked_streams_.AddStream(id, priority); |
760 } | 748 } |
761 | 749 |
762 bool QuicSession::HasDataToWrite() const { | 750 bool QuicSession::HasDataToWrite() const { |
763 return write_blocked_streams_.HasWriteBlockedCryptoOrHeadersStream() || | 751 return write_blocked_streams_.HasWriteBlockedCryptoOrHeadersStream() || |
764 write_blocked_streams_.HasWriteBlockedDataStreams() || | 752 write_blocked_streams_.HasWriteBlockedDataStreams() || |
765 connection_->HasQueuedData(); | 753 connection_->HasQueuedData(); |
766 } | 754 } |
767 | 755 |
768 void QuicSession::PostProcessAfterData() { | 756 void QuicSession::PostProcessAfterData() { |
(...skipping 13 matching lines...) Expand all Loading... |
782 } | 770 } |
783 for (auto const& kv : dynamic_stream_map_) { | 771 for (auto const& kv : dynamic_stream_map_) { |
784 if (kv.second->flow_controller()->IsBlocked()) { | 772 if (kv.second->flow_controller()->IsBlocked()) { |
785 return true; | 773 return true; |
786 } | 774 } |
787 } | 775 } |
788 return false; | 776 return false; |
789 } | 777 } |
790 | 778 |
791 } // namespace net | 779 } // namespace net |
OLD | NEW |