Index: net/quic/quic_session.cc |
diff --git a/net/quic/quic_session.cc b/net/quic/quic_session.cc |
index fc0365bf1eb8a35cd859deb79fe7185ffecc41ac..9f35ba03a175802206bf41b4d6af82ba797a95d1 100644 |
--- a/net/quic/quic_session.cc |
+++ b/net/quic/quic_session.cc |
@@ -8,7 +8,6 @@ |
#include "net/quic/crypto/proof_verifier.h" |
#include "net/quic/quic_connection.h" |
#include "net/quic/quic_flow_controller.h" |
-#include "net/quic/quic_headers_stream.h" |
#include "net/ssl/ssl_info.h" |
using base::StringPiece; |
@@ -89,8 +88,8 @@ class VisitorShim : public QuicConnectionVisitorInterface { |
return session_->HasPendingHandshake(); |
} |
- bool HasOpenDataStreams() const override { |
- return session_->HasOpenDataStreams(); |
+ bool HasOpenDynamicStreams() const override { |
+ return session_->HasOpenDynamicStreams(); |
} |
private: |
@@ -102,8 +101,9 @@ QuicSession::QuicSession(QuicConnection* connection, const QuicConfig& config) |
visitor_shim_(new VisitorShim(this)), |
config_(config), |
max_open_streams_(config_.MaxStreamsPerConnection()), |
- next_stream_id_(perspective() == Perspective::IS_SERVER ? 2 : 5), |
- largest_peer_created_stream_id_(0), |
+ next_stream_id_(perspective() == Perspective::IS_SERVER ? 2 : 3), |
+ largest_peer_created_stream_id_( |
+ perspective() == Perspective::IS_SERVER ? 1 : 0), |
error_(QUIC_NO_ERROR), |
flow_controller_(connection_.get(), |
0, |
@@ -117,17 +117,16 @@ QuicSession::QuicSession(QuicConnection* connection, const QuicConfig& config) |
} |
void QuicSession::Initialize() { |
- // Crypto stream must exist when Initialize is called. |
- DCHECK(GetCryptoStream()); |
- |
connection_->set_visitor(visitor_shim_.get()); |
connection_->SetFromConfig(config_); |
- headers_stream_.reset(new QuicHeadersStream(this)); |
+ |
+ DCHECK_EQ(kCryptoStreamId, GetCryptoStream()->id()); |
+ static_stream_map_[kCryptoStreamId] = GetCryptoStream(); |
} |
QuicSession::~QuicSession() { |
STLDeleteElements(&closed_streams_); |
- STLDeleteValues(&stream_map_); |
+ STLDeleteValues(&dynamic_stream_map_); |
DLOG_IF(WARNING, |
locally_closed_streams_highest_offset_.size() > max_open_streams_) |
@@ -157,52 +156,14 @@ void QuicSession::OnStreamFrames(const vector<QuicStreamFrame>& frames) { |
} |
} |
-void QuicSession::OnStreamHeaders(QuicStreamId stream_id, |
- StringPiece headers_data) { |
- QuicDataStream* stream = GetDataStream(stream_id); |
- if (!stream) { |
- // It's quite possible to receive headers after a stream has been reset. |
- return; |
- } |
- stream->OnStreamHeaders(headers_data); |
-} |
- |
-void QuicSession::OnStreamHeadersPriority(QuicStreamId stream_id, |
- QuicPriority priority) { |
- QuicDataStream* stream = GetDataStream(stream_id); |
- if (!stream) { |
- // It's quite possible to receive headers after a stream has been reset. |
- return; |
- } |
- stream->OnStreamHeadersPriority(priority); |
-} |
- |
-void QuicSession::OnStreamHeadersComplete(QuicStreamId stream_id, |
- bool fin, |
- size_t frame_len) { |
- QuicDataStream* stream = GetDataStream(stream_id); |
- if (!stream) { |
- // It's quite possible to receive headers after a stream has been reset. |
- return; |
- } |
- stream->OnStreamHeadersComplete(fin, frame_len); |
-} |
- |
void QuicSession::OnRstStream(const QuicRstStreamFrame& frame) { |
- if (frame.stream_id == kCryptoStreamId) { |
+ if (ContainsKey(static_stream_map_, frame.stream_id)) { |
connection()->SendConnectionCloseWithDetails( |
- QUIC_INVALID_STREAM_ID, |
- "Attempt to reset the crypto stream"); |
- return; |
- } |
- if (frame.stream_id == kHeadersStreamId) { |
- connection()->SendConnectionCloseWithDetails( |
- QUIC_INVALID_STREAM_ID, |
- "Attempt to reset the headers stream"); |
+ QUIC_INVALID_STREAM_ID, "Attempt to reset a static stream"); |
return; |
} |
- QuicDataStream* stream = GetDataStream(frame.stream_id); |
+ ReliableQuicStream* stream = GetDynamicStream(frame.stream_id); |
if (!stream) { |
// The RST frame contains the final byte offset for the stream: we can now |
// update the connection level flow controller if needed. |
@@ -225,12 +186,12 @@ void QuicSession::OnConnectionClosed(QuicErrorCode error, bool from_peer) { |
error_ = error; |
} |
- while (!stream_map_.empty()) { |
- DataStreamMap::iterator it = stream_map_.begin(); |
+ while (!dynamic_stream_map_.empty()) { |
+ StreamMap::iterator it = dynamic_stream_map_.begin(); |
QuicStreamId id = it->first; |
it->second->OnConnectionClosed(error, from_peer); |
// The stream should call CloseStream as part of OnConnectionClosed. |
- if (stream_map_.find(id) != stream_map_.end()) { |
+ if (dynamic_stream_map_.find(id) != dynamic_stream_map_.end()) { |
LOG(DFATAL) << ENDPOINT |
<< "Stream failed to close under OnConnectionClosed"; |
CloseStream(id); |
@@ -345,7 +306,7 @@ bool QuicSession::HasPendingHandshake() const { |
return has_pending_handshake_; |
} |
-bool QuicSession::HasOpenDataStreams() const { |
+bool QuicSession::HasOpenDynamicStreams() const { |
return GetNumOpenStreams() > 0; |
} |
@@ -360,19 +321,14 @@ QuicConsumedData QuicSession::WritevData( |
ack_notifier_delegate); |
} |
-size_t QuicSession::WriteHeaders( |
- QuicStreamId id, |
- const SpdyHeaderBlock& headers, |
- bool fin, |
- QuicPriority priority, |
- QuicAckNotifier::DelegateInterface* ack_notifier_delegate) { |
- return headers_stream_->WriteHeaders(id, headers, fin, priority, |
- ack_notifier_delegate); |
-} |
- |
void QuicSession::SendRstStream(QuicStreamId id, |
QuicRstStreamErrorCode error, |
QuicStreamOffset bytes_written) { |
+ if (ContainsKey(static_stream_map_, id)) { |
+ LOG(DFATAL) << "Cannot send RST for a static stream with ID " << id; |
+ return; |
+ } |
+ |
if (connection()->connected()) { |
// Only send a RST_STREAM frame if still connected. |
connection_->SendRstStream(id, error, bytes_written); |
@@ -396,12 +352,12 @@ void QuicSession::CloseStreamInner(QuicStreamId stream_id, |
bool locally_reset) { |
DVLOG(1) << ENDPOINT << "Closing stream " << stream_id; |
- DataStreamMap::iterator it = stream_map_.find(stream_id); |
- if (it == stream_map_.end()) { |
+ StreamMap::iterator it = dynamic_stream_map_.find(stream_id); |
+ if (it == dynamic_stream_map_.end()) { |
DVLOG(1) << ENDPOINT << "Stream is already closed: " << stream_id; |
return; |
} |
- QuicDataStream* stream = it->second; |
+ ReliableQuicStream* stream = it->second; |
// Tell the stream that a RST has been sent. |
if (locally_reset) { |
@@ -418,10 +374,10 @@ void QuicSession::CloseStreamInner(QuicStreamId stream_id, |
stream->flow_controller()->highest_received_byte_offset(); |
} |
- stream_map_.erase(it); |
+ dynamic_stream_map_.erase(it); |
stream->OnClose(); |
// Decrease the number of streams being emulated when a new one is opened. |
- connection_->SetNumOpenStreams(stream_map_.size()); |
+ connection_->SetNumOpenStreams(dynamic_stream_map_.size()); |
} |
void QuicSession::UpdateFlowControlOnFinalReceivedByteOffset( |
@@ -493,9 +449,10 @@ void QuicSession::OnConfigNegotiated() { |
void QuicSession::EnableAutoTuneReceiveWindow() { |
flow_controller_.set_auto_tune_receive_window(true); |
// Inform all existing streams about the new window. |
- GetCryptoStream()->flow_controller()->set_auto_tune_receive_window(true); |
- headers_stream_->flow_controller()->set_auto_tune_receive_window(true); |
- for (auto const& kv : stream_map_) { |
+ for (auto const& kv : static_stream_map_) { |
+ kv.second->flow_controller()->set_auto_tune_receive_window(true); |
+ } |
+ for (auto const& kv : dynamic_stream_map_) { |
kv.second->flow_controller()->set_auto_tune_receive_window(true); |
} |
} |
@@ -512,9 +469,10 @@ void QuicSession::OnNewStreamFlowControlWindow(QuicStreamOffset new_window) { |
} |
// Inform all existing streams about the new window. |
- GetCryptoStream()->UpdateSendWindowOffset(new_window); |
- headers_stream_->UpdateSendWindowOffset(new_window); |
- for (auto const& kv : stream_map_) { |
+ for (auto const& kv : static_stream_map_) { |
+ kv.second->UpdateSendWindowOffset(new_window); |
+ } |
+ for (auto const& kv : dynamic_stream_map_) { |
kv.second->UpdateSendWindowOffset(new_window); |
} |
} |
@@ -571,13 +529,13 @@ QuicConfig* QuicSession::config() { |
return &config_; |
} |
-void QuicSession::ActivateStream(QuicDataStream* stream) { |
- DVLOG(1) << ENDPOINT << "num_streams: " << stream_map_.size() |
+void QuicSession::ActivateStream(ReliableQuicStream* stream) { |
+ DVLOG(1) << ENDPOINT << "num_streams: " << dynamic_stream_map_.size() |
<< ". activating " << stream->id(); |
- DCHECK_EQ(stream_map_.count(stream->id()), 0u); |
- stream_map_[stream->id()] = stream; |
+ DCHECK_EQ(dynamic_stream_map_.count(stream->id()), 0u); |
+ dynamic_stream_map_[stream->id()] = stream; |
// Increase the number of streams being emulated when a new one is opened. |
- connection_->SetNumOpenStreams(stream_map_.size()); |
+ connection_->SetNumOpenStreams(dynamic_stream_map_.size()); |
} |
QuicStreamId QuicSession::GetNextStreamId() { |
@@ -587,27 +545,22 @@ QuicStreamId QuicSession::GetNextStreamId() { |
} |
ReliableQuicStream* QuicSession::GetStream(const QuicStreamId stream_id) { |
- if (stream_id == kCryptoStreamId) { |
- return GetCryptoStream(); |
- } |
- if (stream_id == kHeadersStreamId) { |
- return headers_stream_.get(); |
+ StreamMap::iterator it = static_stream_map_.find(stream_id); |
+ if (it != static_stream_map_.end()) { |
+ return it->second; |
} |
- return GetDataStream(stream_id); |
+ return GetDynamicStream(stream_id); |
} |
-QuicDataStream* QuicSession::GetDataStream(const QuicStreamId stream_id) { |
- if (stream_id == kCryptoStreamId) { |
- DLOG(FATAL) << "Attempt to call GetDataStream with the crypto stream id"; |
- return nullptr; |
- } |
- if (stream_id == kHeadersStreamId) { |
- DLOG(FATAL) << "Attempt to call GetDataStream with the headers stream id"; |
+ReliableQuicStream* QuicSession::GetDynamicStream( |
+ const QuicStreamId stream_id) { |
+ if (static_stream_map_.find(stream_id) != static_stream_map_.end()) { |
+ DLOG(FATAL) << "Attempt to call GetDynamicStream for a static stream"; |
return nullptr; |
} |
- DataStreamMap::iterator it = stream_map_.find(stream_id); |
- if (it != stream_map_.end()) { |
+ StreamMap::iterator it = dynamic_stream_map_.find(stream_id); |
+ if (it != dynamic_stream_map_.end()) { |
return it->second; |
} |
@@ -624,10 +577,11 @@ QuicDataStream* QuicSession::GetDataStream(const QuicStreamId stream_id) { |
return nullptr; |
} |
- return GetIncomingDataStream(stream_id); |
+ return GetIncomingDynamicStream(stream_id); |
} |
-QuicDataStream* QuicSession::GetIncomingDataStream(QuicStreamId stream_id) { |
+ReliableQuicStream* QuicSession::GetIncomingDynamicStream( |
+ QuicStreamId stream_id) { |
if (IsClosedStream(stream_id)) { |
return nullptr; |
} |
@@ -646,10 +600,6 @@ QuicDataStream* QuicSession::GetIncomingDataStream(QuicStreamId stream_id) { |
} |
return nullptr; |
} |
- if (largest_peer_created_stream_id_ == 0 && |
- perspective() == Perspective::IS_SERVER) { |
- largest_peer_created_stream_id_ = 3; |
- } |
for (QuicStreamId id = largest_peer_created_stream_id_ + 2; |
id < stream_id; |
id += 2) { |
@@ -657,7 +607,7 @@ QuicDataStream* QuicSession::GetIncomingDataStream(QuicStreamId stream_id) { |
} |
largest_peer_created_stream_id_ = stream_id; |
} |
- QuicDataStream* stream = CreateIncomingDataStream(stream_id); |
+ ReliableQuicStream* stream = CreateIncomingDynamicStream(stream_id); |
if (stream == nullptr) { |
return nullptr; |
} |
@@ -672,13 +622,8 @@ void QuicSession::set_max_open_streams(size_t max_open_streams) { |
bool QuicSession::IsClosedStream(QuicStreamId id) { |
DCHECK_NE(0u, id); |
- if (id == kCryptoStreamId) { |
- return false; |
- } |
- if (id == kHeadersStreamId) { |
- return false; |
- } |
- if (ContainsKey(stream_map_, id)) { |
+ if (ContainsKey(static_stream_map_, id) || |
+ ContainsKey(dynamic_stream_map_, id)) { |
// Stream is active |
return false; |
} |
@@ -694,7 +639,7 @@ bool QuicSession::IsClosedStream(QuicStreamId id) { |
} |
size_t QuicSession::GetNumOpenStreams() const { |
- return stream_map_.size() + implicitly_created_streams_.size(); |
+ return dynamic_stream_map_.size() + implicitly_created_streams_.size(); |
} |
void QuicSession::MarkWriteBlocked(QuicStreamId id, QuicPriority priority) { |
@@ -742,11 +687,12 @@ bool QuicSession::IsConnectionFlowControlBlocked() const { |
} |
bool QuicSession::IsStreamFlowControlBlocked() { |
- if (headers_stream_->flow_controller()->IsBlocked() || |
- GetCryptoStream()->flow_controller()->IsBlocked()) { |
- return true; |
+ for (auto const& kv : static_stream_map_) { |
+ if (kv.second->flow_controller()->IsBlocked()) { |
+ return true; |
+ } |
} |
- for (auto const& kv : stream_map_) { |
+ for (auto const& kv : dynamic_stream_map_) { |
if (kv.second->flow_controller()->IsBlocked()) { |
return true; |
} |