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

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

Issue 1190823003: Remove dependency on headers stream from QuicSession. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@Final_0616
Patch Set: deleted an include Created 5 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
« 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_flow_controller.h" 10 #include "net/quic/quic_flow_controller.h"
11 #include "net/quic/quic_headers_stream.h"
12 #include "net/ssl/ssl_info.h" 11 #include "net/ssl/ssl_info.h"
13 12
14 using base::StringPiece; 13 using base::StringPiece;
15 using base::hash_map; 14 using base::hash_map;
16 using base::hash_set; 15 using base::hash_set;
17 using std::make_pair; 16 using std::make_pair;
18 using std::map; 17 using std::map;
19 using std::max; 18 using std::max;
20 using std::string; 19 using std::string;
21 using std::vector; 20 using std::vector;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 void OnWriteBlocked() override { session_->OnWriteBlocked(); } 81 void OnWriteBlocked() override { session_->OnWriteBlocked(); }
83 82
84 bool WillingAndAbleToWrite() const override { 83 bool WillingAndAbleToWrite() const override {
85 return session_->WillingAndAbleToWrite(); 84 return session_->WillingAndAbleToWrite();
86 } 85 }
87 86
88 bool HasPendingHandshake() const override { 87 bool HasPendingHandshake() const override {
89 return session_->HasPendingHandshake(); 88 return session_->HasPendingHandshake();
90 } 89 }
91 90
92 bool HasOpenDataStreams() const override { 91 bool HasOpenDynamicStreams() const override {
93 return session_->HasOpenDataStreams(); 92 return session_->HasOpenDynamicStreams();
94 } 93 }
95 94
96 private: 95 private:
97 QuicSession* session_; 96 QuicSession* session_;
98 }; 97 };
99 98
100 QuicSession::QuicSession(QuicConnection* connection, const QuicConfig& config) 99 QuicSession::QuicSession(QuicConnection* connection, const QuicConfig& config)
101 : connection_(connection), 100 : connection_(connection),
102 visitor_shim_(new VisitorShim(this)), 101 visitor_shim_(new VisitorShim(this)),
103 config_(config), 102 config_(config),
104 max_open_streams_(config_.MaxStreamsPerConnection()), 103 max_open_streams_(config_.MaxStreamsPerConnection()),
105 next_stream_id_(perspective() == Perspective::IS_SERVER ? 2 : 5), 104 next_stream_id_(perspective() == Perspective::IS_SERVER ? 2 : 3),
106 largest_peer_created_stream_id_(0), 105 largest_peer_created_stream_id_(
106 perspective() == Perspective::IS_SERVER ? 1 : 0),
107 error_(QUIC_NO_ERROR), 107 error_(QUIC_NO_ERROR),
108 flow_controller_(connection_.get(), 108 flow_controller_(connection_.get(),
109 0, 109 0,
110 perspective(), 110 perspective(),
111 kMinimumFlowControlSendWindow, 111 kMinimumFlowControlSendWindow,
112 config_.GetInitialSessionFlowControlWindowToSend(), 112 config_.GetInitialSessionFlowControlWindowToSend(),
113 false), 113 false),
114 goaway_received_(false), 114 goaway_received_(false),
115 goaway_sent_(false), 115 goaway_sent_(false),
116 has_pending_handshake_(false) { 116 has_pending_handshake_(false) {
117 } 117 }
118 118
119 void QuicSession::Initialize() { 119 void QuicSession::Initialize() {
120 // Crypto stream must exist when Initialize is called.
121 DCHECK(GetCryptoStream());
122
123 connection_->set_visitor(visitor_shim_.get()); 120 connection_->set_visitor(visitor_shim_.get());
124 connection_->SetFromConfig(config_); 121 connection_->SetFromConfig(config_);
125 headers_stream_.reset(new QuicHeadersStream(this)); 122
123 DCHECK_EQ(kCryptoStreamId, GetCryptoStream()->id());
124 static_stream_map_[kCryptoStreamId] = GetCryptoStream();
126 } 125 }
127 126
128 QuicSession::~QuicSession() { 127 QuicSession::~QuicSession() {
129 STLDeleteElements(&closed_streams_); 128 STLDeleteElements(&closed_streams_);
130 STLDeleteValues(&stream_map_); 129 STLDeleteValues(&dynamic_stream_map_);
131 130
132 DLOG_IF(WARNING, 131 DLOG_IF(WARNING,
133 locally_closed_streams_highest_offset_.size() > max_open_streams_) 132 locally_closed_streams_highest_offset_.size() > max_open_streams_)
134 << "Surprisingly high number of locally closed streams still waiting for " 133 << "Surprisingly high number of locally closed streams still waiting for "
135 "final byte offset: " << locally_closed_streams_highest_offset_.size(); 134 "final byte offset: " << locally_closed_streams_highest_offset_.size();
136 } 135 }
137 136
138 void QuicSession::OnStreamFrames(const vector<QuicStreamFrame>& frames) { 137 void QuicSession::OnStreamFrames(const vector<QuicStreamFrame>& frames) {
139 for (size_t i = 0; i < frames.size() && connection_->connected(); ++i) { 138 for (size_t i = 0; i < frames.size() && connection_->connected(); ++i) {
140 // TODO(rch) deal with the error case of stream id 0. 139 // TODO(rch) deal with the error case of stream id 0.
141 const QuicStreamFrame& frame = frames[i]; 140 const QuicStreamFrame& frame = frames[i];
142 QuicStreamId stream_id = frame.stream_id; 141 QuicStreamId stream_id = frame.stream_id;
143 ReliableQuicStream* stream = GetStream(stream_id); 142 ReliableQuicStream* stream = GetStream(stream_id);
144 if (!stream) { 143 if (!stream) {
145 // The stream no longer exists, but we may still be interested in the 144 // The stream no longer exists, but we may still be interested in the
146 // final stream byte offset sent by the peer. A frame with a FIN can give 145 // final stream byte offset sent by the peer. A frame with a FIN can give
147 // us this offset. 146 // us this offset.
148 if (frame.fin) { 147 if (frame.fin) {
149 QuicStreamOffset final_byte_offset = frame.offset + frame.data.size(); 148 QuicStreamOffset final_byte_offset = frame.offset + frame.data.size();
150 UpdateFlowControlOnFinalReceivedByteOffset(stream_id, 149 UpdateFlowControlOnFinalReceivedByteOffset(stream_id,
151 final_byte_offset); 150 final_byte_offset);
152 } 151 }
153 152
154 continue; 153 continue;
155 } 154 }
156 stream->OnStreamFrame(frames[i]); 155 stream->OnStreamFrame(frames[i]);
157 } 156 }
158 } 157 }
159 158
160 void QuicSession::OnStreamHeaders(QuicStreamId stream_id,
161 StringPiece headers_data) {
162 QuicDataStream* stream = GetDataStream(stream_id);
163 if (!stream) {
164 // It's quite possible to receive headers after a stream has been reset.
165 return;
166 }
167 stream->OnStreamHeaders(headers_data);
168 }
169
170 void QuicSession::OnStreamHeadersPriority(QuicStreamId stream_id,
171 QuicPriority priority) {
172 QuicDataStream* stream = GetDataStream(stream_id);
173 if (!stream) {
174 // It's quite possible to receive headers after a stream has been reset.
175 return;
176 }
177 stream->OnStreamHeadersPriority(priority);
178 }
179
180 void QuicSession::OnStreamHeadersComplete(QuicStreamId stream_id,
181 bool fin,
182 size_t frame_len) {
183 QuicDataStream* stream = GetDataStream(stream_id);
184 if (!stream) {
185 // It's quite possible to receive headers after a stream has been reset.
186 return;
187 }
188 stream->OnStreamHeadersComplete(fin, frame_len);
189 }
190
191 void QuicSession::OnRstStream(const QuicRstStreamFrame& frame) { 159 void QuicSession::OnRstStream(const QuicRstStreamFrame& frame) {
192 if (frame.stream_id == kCryptoStreamId) { 160 if (ContainsKey(static_stream_map_, frame.stream_id)) {
193 connection()->SendConnectionCloseWithDetails( 161 connection()->SendConnectionCloseWithDetails(
194 QUIC_INVALID_STREAM_ID, 162 QUIC_INVALID_STREAM_ID, "Attempt to reset a static stream");
195 "Attempt to reset the crypto stream");
196 return;
197 }
198 if (frame.stream_id == kHeadersStreamId) {
199 connection()->SendConnectionCloseWithDetails(
200 QUIC_INVALID_STREAM_ID,
201 "Attempt to reset the headers stream");
202 return; 163 return;
203 } 164 }
204 165
205 QuicDataStream* stream = GetDataStream(frame.stream_id); 166 ReliableQuicStream* stream = GetDynamicStream(frame.stream_id);
206 if (!stream) { 167 if (!stream) {
207 // The RST frame contains the final byte offset for the stream: we can now 168 // The RST frame contains the final byte offset for the stream: we can now
208 // update the connection level flow controller if needed. 169 // update the connection level flow controller if needed.
209 UpdateFlowControlOnFinalReceivedByteOffset(frame.stream_id, 170 UpdateFlowControlOnFinalReceivedByteOffset(frame.stream_id,
210 frame.byte_offset); 171 frame.byte_offset);
211 return; // Errors are handled by GetStream. 172 return; // Errors are handled by GetStream.
212 } 173 }
213 174
214 stream->OnStreamReset(frame); 175 stream->OnStreamReset(frame);
215 } 176 }
216 177
217 void QuicSession::OnGoAway(const QuicGoAwayFrame& frame) { 178 void QuicSession::OnGoAway(const QuicGoAwayFrame& frame) {
218 DCHECK(frame.last_good_stream_id < next_stream_id_); 179 DCHECK(frame.last_good_stream_id < next_stream_id_);
219 goaway_received_ = true; 180 goaway_received_ = true;
220 } 181 }
221 182
222 void QuicSession::OnConnectionClosed(QuicErrorCode error, bool from_peer) { 183 void QuicSession::OnConnectionClosed(QuicErrorCode error, bool from_peer) {
223 DCHECK(!connection_->connected()); 184 DCHECK(!connection_->connected());
224 if (error_ == QUIC_NO_ERROR) { 185 if (error_ == QUIC_NO_ERROR) {
225 error_ = error; 186 error_ = error;
226 } 187 }
227 188
228 while (!stream_map_.empty()) { 189 while (!dynamic_stream_map_.empty()) {
229 DataStreamMap::iterator it = stream_map_.begin(); 190 StreamMap::iterator it = dynamic_stream_map_.begin();
230 QuicStreamId id = it->first; 191 QuicStreamId id = it->first;
231 it->second->OnConnectionClosed(error, from_peer); 192 it->second->OnConnectionClosed(error, from_peer);
232 // The stream should call CloseStream as part of OnConnectionClosed. 193 // The stream should call CloseStream as part of OnConnectionClosed.
233 if (stream_map_.find(id) != stream_map_.end()) { 194 if (dynamic_stream_map_.find(id) != dynamic_stream_map_.end()) {
234 LOG(DFATAL) << ENDPOINT 195 LOG(DFATAL) << ENDPOINT
235 << "Stream failed to close under OnConnectionClosed"; 196 << "Stream failed to close under OnConnectionClosed";
236 CloseStream(id); 197 CloseStream(id);
237 } 198 }
238 } 199 }
239 } 200 }
240 201
241 void QuicSession::OnSuccessfulVersionNegotiation(const QuicVersion& version) { 202 void QuicSession::OnSuccessfulVersionNegotiation(const QuicVersion& version) {
242 } 203 }
243 204
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 // level. 299 // level.
339 return write_blocked_streams_.HasWriteBlockedCryptoOrHeadersStream() || 300 return write_blocked_streams_.HasWriteBlockedCryptoOrHeadersStream() ||
340 (!flow_controller_.IsBlocked() && 301 (!flow_controller_.IsBlocked() &&
341 write_blocked_streams_.HasWriteBlockedDataStreams()); 302 write_blocked_streams_.HasWriteBlockedDataStreams());
342 } 303 }
343 304
344 bool QuicSession::HasPendingHandshake() const { 305 bool QuicSession::HasPendingHandshake() const {
345 return has_pending_handshake_; 306 return has_pending_handshake_;
346 } 307 }
347 308
348 bool QuicSession::HasOpenDataStreams() const { 309 bool QuicSession::HasOpenDynamicStreams() const {
349 return GetNumOpenStreams() > 0; 310 return GetNumOpenStreams() > 0;
350 } 311 }
351 312
352 QuicConsumedData QuicSession::WritevData( 313 QuicConsumedData QuicSession::WritevData(
353 QuicStreamId id, 314 QuicStreamId id,
354 const IOVector& data, 315 const IOVector& data,
355 QuicStreamOffset offset, 316 QuicStreamOffset offset,
356 bool fin, 317 bool fin,
357 FecProtection fec_protection, 318 FecProtection fec_protection,
358 QuicAckNotifier::DelegateInterface* ack_notifier_delegate) { 319 QuicAckNotifier::DelegateInterface* ack_notifier_delegate) {
359 return connection_->SendStreamData(id, data, offset, fin, fec_protection, 320 return connection_->SendStreamData(id, data, offset, fin, fec_protection,
360 ack_notifier_delegate); 321 ack_notifier_delegate);
361 } 322 }
362 323
363 size_t QuicSession::WriteHeaders(
364 QuicStreamId id,
365 const SpdyHeaderBlock& headers,
366 bool fin,
367 QuicPriority priority,
368 QuicAckNotifier::DelegateInterface* ack_notifier_delegate) {
369 return headers_stream_->WriteHeaders(id, headers, fin, priority,
370 ack_notifier_delegate);
371 }
372
373 void QuicSession::SendRstStream(QuicStreamId id, 324 void QuicSession::SendRstStream(QuicStreamId id,
374 QuicRstStreamErrorCode error, 325 QuicRstStreamErrorCode error,
375 QuicStreamOffset bytes_written) { 326 QuicStreamOffset bytes_written) {
327 if (ContainsKey(static_stream_map_, id)) {
328 LOG(DFATAL) << "Cannot send RST for a static stream with ID " << id;
329 return;
330 }
331
376 if (connection()->connected()) { 332 if (connection()->connected()) {
377 // Only send a RST_STREAM frame if still connected. 333 // Only send a RST_STREAM frame if still connected.
378 connection_->SendRstStream(id, error, bytes_written); 334 connection_->SendRstStream(id, error, bytes_written);
379 } 335 }
380 CloseStreamInner(id, true); 336 CloseStreamInner(id, true);
381 } 337 }
382 338
383 void QuicSession::SendGoAway(QuicErrorCode error_code, const string& reason) { 339 void QuicSession::SendGoAway(QuicErrorCode error_code, const string& reason) {
384 if (goaway_sent_) { 340 if (goaway_sent_) {
385 return; 341 return;
386 } 342 }
387 goaway_sent_ = true; 343 goaway_sent_ = true;
388 connection_->SendGoAway(error_code, largest_peer_created_stream_id_, reason); 344 connection_->SendGoAway(error_code, largest_peer_created_stream_id_, reason);
389 } 345 }
390 346
391 void QuicSession::CloseStream(QuicStreamId stream_id) { 347 void QuicSession::CloseStream(QuicStreamId stream_id) {
392 CloseStreamInner(stream_id, false); 348 CloseStreamInner(stream_id, false);
393 } 349 }
394 350
395 void QuicSession::CloseStreamInner(QuicStreamId stream_id, 351 void QuicSession::CloseStreamInner(QuicStreamId stream_id,
396 bool locally_reset) { 352 bool locally_reset) {
397 DVLOG(1) << ENDPOINT << "Closing stream " << stream_id; 353 DVLOG(1) << ENDPOINT << "Closing stream " << stream_id;
398 354
399 DataStreamMap::iterator it = stream_map_.find(stream_id); 355 StreamMap::iterator it = dynamic_stream_map_.find(stream_id);
400 if (it == stream_map_.end()) { 356 if (it == dynamic_stream_map_.end()) {
401 DVLOG(1) << ENDPOINT << "Stream is already closed: " << stream_id; 357 DVLOG(1) << ENDPOINT << "Stream is already closed: " << stream_id;
402 return; 358 return;
403 } 359 }
404 QuicDataStream* stream = it->second; 360 ReliableQuicStream* stream = it->second;
405 361
406 // Tell the stream that a RST has been sent. 362 // Tell the stream that a RST has been sent.
407 if (locally_reset) { 363 if (locally_reset) {
408 stream->set_rst_sent(true); 364 stream->set_rst_sent(true);
409 } 365 }
410 366
411 closed_streams_.push_back(it->second); 367 closed_streams_.push_back(it->second);
412 368
413 // If we haven't received a FIN or RST for this stream, we need to keep track 369 // If we haven't received a FIN or RST for this stream, we need to keep track
414 // of the how many bytes the stream's flow controller believes it has 370 // of the how many bytes the stream's flow controller believes it has
415 // received, for accurate connection level flow control accounting. 371 // received, for accurate connection level flow control accounting.
416 if (!stream->HasFinalReceivedByteOffset()) { 372 if (!stream->HasFinalReceivedByteOffset()) {
417 locally_closed_streams_highest_offset_[stream_id] = 373 locally_closed_streams_highest_offset_[stream_id] =
418 stream->flow_controller()->highest_received_byte_offset(); 374 stream->flow_controller()->highest_received_byte_offset();
419 } 375 }
420 376
421 stream_map_.erase(it); 377 dynamic_stream_map_.erase(it);
422 stream->OnClose(); 378 stream->OnClose();
423 // Decrease the number of streams being emulated when a new one is opened. 379 // Decrease the number of streams being emulated when a new one is opened.
424 connection_->SetNumOpenStreams(stream_map_.size()); 380 connection_->SetNumOpenStreams(dynamic_stream_map_.size());
425 } 381 }
426 382
427 void QuicSession::UpdateFlowControlOnFinalReceivedByteOffset( 383 void QuicSession::UpdateFlowControlOnFinalReceivedByteOffset(
428 QuicStreamId stream_id, QuicStreamOffset final_byte_offset) { 384 QuicStreamId stream_id, QuicStreamOffset final_byte_offset) {
429 map<QuicStreamId, QuicStreamOffset>::iterator it = 385 map<QuicStreamId, QuicStreamOffset>::iterator it =
430 locally_closed_streams_highest_offset_.find(stream_id); 386 locally_closed_streams_highest_offset_.find(stream_id);
431 if (it == locally_closed_streams_highest_offset_.end()) { 387 if (it == locally_closed_streams_highest_offset_.end()) {
432 return; 388 return;
433 } 389 }
434 390
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 } 442 }
487 if (config_.HasReceivedInitialSessionFlowControlWindowBytes()) { 443 if (config_.HasReceivedInitialSessionFlowControlWindowBytes()) {
488 OnNewSessionFlowControlWindow( 444 OnNewSessionFlowControlWindow(
489 config_.ReceivedInitialSessionFlowControlWindowBytes()); 445 config_.ReceivedInitialSessionFlowControlWindowBytes());
490 } 446 }
491 } 447 }
492 448
493 void QuicSession::EnableAutoTuneReceiveWindow() { 449 void QuicSession::EnableAutoTuneReceiveWindow() {
494 flow_controller_.set_auto_tune_receive_window(true); 450 flow_controller_.set_auto_tune_receive_window(true);
495 // Inform all existing streams about the new window. 451 // Inform all existing streams about the new window.
496 GetCryptoStream()->flow_controller()->set_auto_tune_receive_window(true); 452 for (auto const& kv : static_stream_map_) {
497 headers_stream_->flow_controller()->set_auto_tune_receive_window(true); 453 kv.second->flow_controller()->set_auto_tune_receive_window(true);
498 for (auto const& kv : stream_map_) { 454 }
455 for (auto const& kv : dynamic_stream_map_) {
499 kv.second->flow_controller()->set_auto_tune_receive_window(true); 456 kv.second->flow_controller()->set_auto_tune_receive_window(true);
500 } 457 }
501 } 458 }
502 459
503 void QuicSession::OnNewStreamFlowControlWindow(QuicStreamOffset new_window) { 460 void QuicSession::OnNewStreamFlowControlWindow(QuicStreamOffset new_window) {
504 if (new_window < kMinimumFlowControlSendWindow) { 461 if (new_window < kMinimumFlowControlSendWindow) {
505 LOG(ERROR) << "Peer sent us an invalid stream flow control send window: " 462 LOG(ERROR) << "Peer sent us an invalid stream flow control send window: "
506 << new_window 463 << new_window
507 << ", below default: " << kMinimumFlowControlSendWindow; 464 << ", below default: " << kMinimumFlowControlSendWindow;
508 if (connection_->connected()) { 465 if (connection_->connected()) {
509 connection_->SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW); 466 connection_->SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW);
510 } 467 }
511 return; 468 return;
512 } 469 }
513 470
514 // Inform all existing streams about the new window. 471 // Inform all existing streams about the new window.
515 GetCryptoStream()->UpdateSendWindowOffset(new_window); 472 for (auto const& kv : static_stream_map_) {
516 headers_stream_->UpdateSendWindowOffset(new_window); 473 kv.second->UpdateSendWindowOffset(new_window);
517 for (auto const& kv : stream_map_) { 474 }
475 for (auto const& kv : dynamic_stream_map_) {
518 kv.second->UpdateSendWindowOffset(new_window); 476 kv.second->UpdateSendWindowOffset(new_window);
519 } 477 }
520 } 478 }
521 479
522 void QuicSession::OnNewSessionFlowControlWindow(QuicStreamOffset new_window) { 480 void QuicSession::OnNewSessionFlowControlWindow(QuicStreamOffset new_window) {
523 if (new_window < kMinimumFlowControlSendWindow) { 481 if (new_window < kMinimumFlowControlSendWindow) {
524 LOG(ERROR) << "Peer sent us an invalid session flow control send window: " 482 LOG(ERROR) << "Peer sent us an invalid session flow control send window: "
525 << new_window 483 << new_window
526 << ", below default: " << kMinimumFlowControlSendWindow; 484 << ", below default: " << kMinimumFlowControlSendWindow;
527 if (connection_->connected()) { 485 if (connection_->connected()) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 } 522 }
565 523
566 void QuicSession::OnCryptoHandshakeMessageReceived( 524 void QuicSession::OnCryptoHandshakeMessageReceived(
567 const CryptoHandshakeMessage& message) { 525 const CryptoHandshakeMessage& message) {
568 } 526 }
569 527
570 QuicConfig* QuicSession::config() { 528 QuicConfig* QuicSession::config() {
571 return &config_; 529 return &config_;
572 } 530 }
573 531
574 void QuicSession::ActivateStream(QuicDataStream* stream) { 532 void QuicSession::ActivateStream(ReliableQuicStream* stream) {
575 DVLOG(1) << ENDPOINT << "num_streams: " << stream_map_.size() 533 DVLOG(1) << ENDPOINT << "num_streams: " << dynamic_stream_map_.size()
576 << ". activating " << stream->id(); 534 << ". activating " << stream->id();
577 DCHECK_EQ(stream_map_.count(stream->id()), 0u); 535 DCHECK_EQ(dynamic_stream_map_.count(stream->id()), 0u);
578 stream_map_[stream->id()] = stream; 536 dynamic_stream_map_[stream->id()] = stream;
579 // Increase the number of streams being emulated when a new one is opened. 537 // Increase the number of streams being emulated when a new one is opened.
580 connection_->SetNumOpenStreams(stream_map_.size()); 538 connection_->SetNumOpenStreams(dynamic_stream_map_.size());
581 } 539 }
582 540
583 QuicStreamId QuicSession::GetNextStreamId() { 541 QuicStreamId QuicSession::GetNextStreamId() {
584 QuicStreamId id = next_stream_id_; 542 QuicStreamId id = next_stream_id_;
585 next_stream_id_ += 2; 543 next_stream_id_ += 2;
586 return id; 544 return id;
587 } 545 }
588 546
589 ReliableQuicStream* QuicSession::GetStream(const QuicStreamId stream_id) { 547 ReliableQuicStream* QuicSession::GetStream(const QuicStreamId stream_id) {
590 if (stream_id == kCryptoStreamId) { 548 StreamMap::iterator it = static_stream_map_.find(stream_id);
591 return GetCryptoStream(); 549 if (it != static_stream_map_.end()) {
550 return it->second;
592 } 551 }
593 if (stream_id == kHeadersStreamId) { 552 return GetDynamicStream(stream_id);
594 return headers_stream_.get();
595 }
596 return GetDataStream(stream_id);
597 } 553 }
598 554
599 QuicDataStream* QuicSession::GetDataStream(const QuicStreamId stream_id) { 555 ReliableQuicStream* QuicSession::GetDynamicStream(
600 if (stream_id == kCryptoStreamId) { 556 const QuicStreamId stream_id) {
601 DLOG(FATAL) << "Attempt to call GetDataStream with the crypto stream id"; 557 if (static_stream_map_.find(stream_id) != static_stream_map_.end()) {
602 return nullptr; 558 DLOG(FATAL) << "Attempt to call GetDynamicStream for a static stream";
603 }
604 if (stream_id == kHeadersStreamId) {
605 DLOG(FATAL) << "Attempt to call GetDataStream with the headers stream id";
606 return nullptr; 559 return nullptr;
607 } 560 }
608 561
609 DataStreamMap::iterator it = stream_map_.find(stream_id); 562 StreamMap::iterator it = dynamic_stream_map_.find(stream_id);
610 if (it != stream_map_.end()) { 563 if (it != dynamic_stream_map_.end()) {
611 return it->second; 564 return it->second;
612 } 565 }
613 566
614 if (IsClosedStream(stream_id)) { 567 if (IsClosedStream(stream_id)) {
615 return nullptr; 568 return nullptr;
616 } 569 }
617 570
618 if (stream_id % 2 == next_stream_id_ % 2) { 571 if (stream_id % 2 == next_stream_id_ % 2) {
619 // We've received a frame for a locally-created stream that is not 572 // We've received a frame for a locally-created stream that is not
620 // currently active. This is an error. 573 // currently active. This is an error.
621 if (connection()->connected()) { 574 if (connection()->connected()) {
622 connection()->SendConnectionClose(QUIC_PACKET_FOR_NONEXISTENT_STREAM); 575 connection()->SendConnectionClose(QUIC_PACKET_FOR_NONEXISTENT_STREAM);
623 } 576 }
624 return nullptr; 577 return nullptr;
625 } 578 }
626 579
627 return GetIncomingDataStream(stream_id); 580 return GetIncomingDynamicStream(stream_id);
628 } 581 }
629 582
630 QuicDataStream* QuicSession::GetIncomingDataStream(QuicStreamId stream_id) { 583 ReliableQuicStream* QuicSession::GetIncomingDynamicStream(
584 QuicStreamId stream_id) {
631 if (IsClosedStream(stream_id)) { 585 if (IsClosedStream(stream_id)) {
632 return nullptr; 586 return nullptr;
633 } 587 }
634 588
635 implicitly_created_streams_.erase(stream_id); 589 implicitly_created_streams_.erase(stream_id);
636 if (stream_id > largest_peer_created_stream_id_) { 590 if (stream_id > largest_peer_created_stream_id_) {
637 if (stream_id - largest_peer_created_stream_id_ > kMaxStreamIdDelta) { 591 if (stream_id - largest_peer_created_stream_id_ > kMaxStreamIdDelta) {
638 // We may already have sent a connection close due to multiple reset 592 // We may already have sent a connection close due to multiple reset
639 // streams in the same packet. 593 // streams in the same packet.
640 if (connection()->connected()) { 594 if (connection()->connected()) {
641 LOG(ERROR) << "Trying to get stream: " << stream_id 595 LOG(ERROR) << "Trying to get stream: " << stream_id
642 << ", largest peer created stream: " 596 << ", largest peer created stream: "
643 << largest_peer_created_stream_id_ 597 << largest_peer_created_stream_id_
644 << ", max delta: " << kMaxStreamIdDelta; 598 << ", max delta: " << kMaxStreamIdDelta;
645 connection()->SendConnectionClose(QUIC_INVALID_STREAM_ID); 599 connection()->SendConnectionClose(QUIC_INVALID_STREAM_ID);
646 } 600 }
647 return nullptr; 601 return nullptr;
648 } 602 }
649 if (largest_peer_created_stream_id_ == 0 &&
650 perspective() == Perspective::IS_SERVER) {
651 largest_peer_created_stream_id_ = 3;
652 }
653 for (QuicStreamId id = largest_peer_created_stream_id_ + 2; 603 for (QuicStreamId id = largest_peer_created_stream_id_ + 2;
654 id < stream_id; 604 id < stream_id;
655 id += 2) { 605 id += 2) {
656 implicitly_created_streams_.insert(id); 606 implicitly_created_streams_.insert(id);
657 } 607 }
658 largest_peer_created_stream_id_ = stream_id; 608 largest_peer_created_stream_id_ = stream_id;
659 } 609 }
660 QuicDataStream* stream = CreateIncomingDataStream(stream_id); 610 ReliableQuicStream* stream = CreateIncomingDynamicStream(stream_id);
661 if (stream == nullptr) { 611 if (stream == nullptr) {
662 return nullptr; 612 return nullptr;
663 } 613 }
664 ActivateStream(stream); 614 ActivateStream(stream);
665 return stream; 615 return stream;
666 } 616 }
667 617
668 void QuicSession::set_max_open_streams(size_t max_open_streams) { 618 void QuicSession::set_max_open_streams(size_t max_open_streams) {
669 DVLOG(1) << "Setting max_open_streams_ to " << max_open_streams; 619 DVLOG(1) << "Setting max_open_streams_ to " << max_open_streams;
670 max_open_streams_ = max_open_streams; 620 max_open_streams_ = max_open_streams;
671 } 621 }
672 622
673 bool QuicSession::IsClosedStream(QuicStreamId id) { 623 bool QuicSession::IsClosedStream(QuicStreamId id) {
674 DCHECK_NE(0u, id); 624 DCHECK_NE(0u, id);
675 if (id == kCryptoStreamId) { 625 if (ContainsKey(static_stream_map_, id) ||
676 return false; 626 ContainsKey(dynamic_stream_map_, id)) {
677 }
678 if (id == kHeadersStreamId) {
679 return false;
680 }
681 if (ContainsKey(stream_map_, id)) {
682 // Stream is active 627 // Stream is active
683 return false; 628 return false;
684 } 629 }
685 if (id % 2 == next_stream_id_ % 2) { 630 if (id % 2 == next_stream_id_ % 2) {
686 // Locally created streams are strictly in-order. If the id is in the 631 // Locally created streams are strictly in-order. If the id is in the
687 // range of created streams and it's not active, it must have been closed. 632 // range of created streams and it's not active, it must have been closed.
688 return id < next_stream_id_; 633 return id < next_stream_id_;
689 } 634 }
690 // For peer created streams, we also need to consider implicitly created 635 // For peer created streams, we also need to consider implicitly created
691 // streams. 636 // streams.
692 return id <= largest_peer_created_stream_id_ && 637 return id <= largest_peer_created_stream_id_ &&
693 !ContainsKey(implicitly_created_streams_, id); 638 !ContainsKey(implicitly_created_streams_, id);
694 } 639 }
695 640
696 size_t QuicSession::GetNumOpenStreams() const { 641 size_t QuicSession::GetNumOpenStreams() const {
697 return stream_map_.size() + implicitly_created_streams_.size(); 642 return dynamic_stream_map_.size() + implicitly_created_streams_.size();
698 } 643 }
699 644
700 void QuicSession::MarkWriteBlocked(QuicStreamId id, QuicPriority priority) { 645 void QuicSession::MarkWriteBlocked(QuicStreamId id, QuicPriority priority) {
701 #ifndef NDEBUG 646 #ifndef NDEBUG
702 ReliableQuicStream* stream = GetStream(id); 647 ReliableQuicStream* stream = GetStream(id);
703 if (stream != nullptr) { 648 if (stream != nullptr) {
704 LOG_IF(DFATAL, priority != stream->EffectivePriority()) 649 LOG_IF(DFATAL, priority != stream->EffectivePriority())
705 << ENDPOINT << "Stream " << id 650 << ENDPOINT << "Stream " << id
706 << "Priorities do not match. Got: " << priority 651 << "Priorities do not match. Got: " << priority
707 << " Expected: " << stream->EffectivePriority(); 652 << " Expected: " << stream->EffectivePriority();
(...skipping 27 matching lines...) Expand all
735 // A buggy client may fail to send FIN/RSTs. Don't tolerate this. 680 // A buggy client may fail to send FIN/RSTs. Don't tolerate this.
736 connection_->SendConnectionClose(QUIC_TOO_MANY_UNFINISHED_STREAMS); 681 connection_->SendConnectionClose(QUIC_TOO_MANY_UNFINISHED_STREAMS);
737 } 682 }
738 } 683 }
739 684
740 bool QuicSession::IsConnectionFlowControlBlocked() const { 685 bool QuicSession::IsConnectionFlowControlBlocked() const {
741 return flow_controller_.IsBlocked(); 686 return flow_controller_.IsBlocked();
742 } 687 }
743 688
744 bool QuicSession::IsStreamFlowControlBlocked() { 689 bool QuicSession::IsStreamFlowControlBlocked() {
745 if (headers_stream_->flow_controller()->IsBlocked() || 690 for (auto const& kv : static_stream_map_) {
746 GetCryptoStream()->flow_controller()->IsBlocked()) {
747 return true;
748 }
749 for (auto const& kv : stream_map_) {
750 if (kv.second->flow_controller()->IsBlocked()) { 691 if (kv.second->flow_controller()->IsBlocked()) {
751 return true; 692 return true;
752 } 693 }
694 }
695 for (auto const& kv : dynamic_stream_map_) {
696 if (kv.second->flow_controller()->IsBlocked()) {
697 return true;
698 }
753 } 699 }
754 return false; 700 return false;
755 } 701 }
756 702
757 } // namespace net 703 } // 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