| 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/core/quic_session.h" | 5 #include "net/quic/core/quic_session.h" |
| 6 | 6 |
| 7 #include "base/memory/ptr_util.h" | 7 #include "base/memory/ptr_util.h" |
| 8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
| 9 #include "net/quic/core/crypto/proof_verifier.h" | 9 #include "net/quic/core/crypto/proof_verifier.h" |
| 10 #include "net/quic/core/quic_connection.h" | 10 #include "net/quic/core/quic_connection.h" |
| 11 #include "net/quic/core/quic_flags.h" | 11 #include "net/quic/core/quic_flags.h" |
| 12 #include "net/quic/core/quic_flow_controller.h" | 12 #include "net/quic/core/quic_flow_controller.h" |
| 13 #include "net/quic/platform/api/quic_bug_tracker.h" | 13 #include "net/quic/platform/api/quic_bug_tracker.h" |
| 14 #include "net/quic/platform/api/quic_logging.h" |
| 14 #include "net/quic/platform/api/quic_str_cat.h" | 15 #include "net/quic/platform/api/quic_str_cat.h" |
| 15 | 16 |
| 16 using base::StringPiece; | 17 using base::StringPiece; |
| 17 using std::string; | 18 using std::string; |
| 18 | 19 |
| 19 namespace net { | 20 namespace net { |
| 20 | 21 |
| 21 #define ENDPOINT \ | 22 #define ENDPOINT \ |
| 22 (perspective() == Perspective::IS_SERVER ? "Server: " : " Client: ") | 23 (perspective() == Perspective::IS_SERVER ? "Server: " : " Client: ") |
| 23 | 24 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 46 | 47 |
| 47 void QuicSession::Initialize() { | 48 void QuicSession::Initialize() { |
| 48 connection_->set_visitor(this); | 49 connection_->set_visitor(this); |
| 49 connection_->SetFromConfig(config_); | 50 connection_->SetFromConfig(config_); |
| 50 | 51 |
| 51 DCHECK_EQ(kCryptoStreamId, GetCryptoStream()->id()); | 52 DCHECK_EQ(kCryptoStreamId, GetCryptoStream()->id()); |
| 52 static_stream_map_[kCryptoStreamId] = GetCryptoStream(); | 53 static_stream_map_[kCryptoStreamId] = GetCryptoStream(); |
| 53 } | 54 } |
| 54 | 55 |
| 55 QuicSession::~QuicSession() { | 56 QuicSession::~QuicSession() { |
| 56 DLOG_IF(WARNING, num_locally_closed_incoming_streams_highest_offset() > | 57 QUIC_LOG_IF(WARNING, num_locally_closed_incoming_streams_highest_offset() > |
| 57 max_open_incoming_streams_) | 58 max_open_incoming_streams_) |
| 58 << "Surprisingly high number of locally closed peer initiated streams" | 59 << "Surprisingly high number of locally closed peer initiated streams" |
| 59 "still waiting for final byte offset: " | 60 "still waiting for final byte offset: " |
| 60 << num_locally_closed_incoming_streams_highest_offset(); | 61 << num_locally_closed_incoming_streams_highest_offset(); |
| 61 DLOG_IF(WARNING, GetNumLocallyClosedOutgoingStreamsHighestOffset() > | 62 QUIC_LOG_IF(WARNING, GetNumLocallyClosedOutgoingStreamsHighestOffset() > |
| 62 max_open_outgoing_streams_) | 63 max_open_outgoing_streams_) |
| 63 << "Surprisingly high number of locally closed self initiated streams" | 64 << "Surprisingly high number of locally closed self initiated streams" |
| 64 "still waiting for final byte offset: " | 65 "still waiting for final byte offset: " |
| 65 << GetNumLocallyClosedOutgoingStreamsHighestOffset(); | 66 << GetNumLocallyClosedOutgoingStreamsHighestOffset(); |
| 66 } | 67 } |
| 67 | 68 |
| 68 void QuicSession::OnStreamFrame(const QuicStreamFrame& frame) { | 69 void QuicSession::OnStreamFrame(const QuicStreamFrame& frame) { |
| 69 // TODO(rch) deal with the error case of stream id 0. | 70 // TODO(rch) deal with the error case of stream id 0. |
| 70 QuicStreamId stream_id = frame.stream_id; | 71 QuicStreamId stream_id = frame.stream_id; |
| 71 QuicStream* stream = GetOrCreateStream(stream_id); | 72 QuicStream* stream = GetOrCreateStream(stream_id); |
| 72 if (!stream) { | 73 if (!stream) { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 | 140 |
| 140 void QuicSession::OnPathDegrading() {} | 141 void QuicSession::OnPathDegrading() {} |
| 141 | 142 |
| 142 void QuicSession::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) { | 143 void QuicSession::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) { |
| 143 // Stream may be closed by the time we receive a WINDOW_UPDATE, so we can't | 144 // Stream may be closed by the time we receive a WINDOW_UPDATE, so we can't |
| 144 // assume that it still exists. | 145 // assume that it still exists. |
| 145 QuicStreamId stream_id = frame.stream_id; | 146 QuicStreamId stream_id = frame.stream_id; |
| 146 if (stream_id == kConnectionLevelId) { | 147 if (stream_id == kConnectionLevelId) { |
| 147 // This is a window update that applies to the connection, rather than an | 148 // This is a window update that applies to the connection, rather than an |
| 148 // individual stream. | 149 // individual stream. |
| 149 DVLOG(1) << ENDPOINT << "Received connection level flow control window " | 150 QUIC_DLOG(INFO) << ENDPOINT |
| 150 "update with byte offset: " | 151 << "Received connection level flow control window " |
| 151 << frame.byte_offset; | 152 "update with byte offset: " |
| 153 << frame.byte_offset; |
| 152 flow_controller_.UpdateSendWindowOffset(frame.byte_offset); | 154 flow_controller_.UpdateSendWindowOffset(frame.byte_offset); |
| 153 return; | 155 return; |
| 154 } | 156 } |
| 155 QuicStream* stream = GetOrCreateStream(stream_id); | 157 QuicStream* stream = GetOrCreateStream(stream_id); |
| 156 if (stream != nullptr) { | 158 if (stream != nullptr) { |
| 157 stream->OnWindowUpdateFrame(frame); | 159 stream->OnWindowUpdateFrame(frame); |
| 158 } | 160 } |
| 159 } | 161 } |
| 160 | 162 |
| 161 void QuicSession::OnBlockedFrame(const QuicBlockedFrame& frame) { | 163 void QuicSession::OnBlockedFrame(const QuicBlockedFrame& frame) { |
| 162 // TODO(rjshade): Compare our flow control receive windows for specified | 164 // TODO(rjshade): Compare our flow control receive windows for specified |
| 163 // streams: if we have a large window then maybe something | 165 // streams: if we have a large window then maybe something |
| 164 // had gone wrong with the flow control accounting. | 166 // had gone wrong with the flow control accounting. |
| 165 DVLOG(1) << ENDPOINT | 167 QUIC_DLOG(INFO) << ENDPOINT << "Received BLOCKED frame with stream id: " |
| 166 << "Received BLOCKED frame with stream id: " << frame.stream_id; | 168 << frame.stream_id; |
| 167 } | 169 } |
| 168 | 170 |
| 169 bool QuicSession::CheckStreamNotBusyLooping(QuicStream* stream, | 171 bool QuicSession::CheckStreamNotBusyLooping(QuicStream* stream, |
| 170 uint64_t previous_bytes_written, | 172 uint64_t previous_bytes_written, |
| 171 bool previous_fin_sent) { | 173 bool previous_fin_sent) { |
| 172 if ( // Stream should not be closed. | 174 if ( // Stream should not be closed. |
| 173 !stream->write_side_closed() && | 175 !stream->write_side_closed() && |
| 174 // Not connection flow control blocked. | 176 // Not connection flow control blocked. |
| 175 !flow_controller_.IsBlocked() && | 177 !flow_controller_.IsBlocked() && |
| 176 // Detect lack of forward progress. | 178 // Detect lack of forward progress. |
| 177 previous_bytes_written == stream->stream_bytes_written() && | 179 previous_bytes_written == stream->stream_bytes_written() && |
| 178 previous_fin_sent == stream->fin_sent()) { | 180 previous_fin_sent == stream->fin_sent()) { |
| 179 stream->set_busy_counter(stream->busy_counter() + 1); | 181 stream->set_busy_counter(stream->busy_counter() + 1); |
| 180 DVLOG(1) << "Suspected busy loop on stream id " << stream->id() | 182 QUIC_DVLOG(1) << "Suspected busy loop on stream id " << stream->id() |
| 181 << " stream_bytes_written " << stream->stream_bytes_written() | 183 << " stream_bytes_written " << stream->stream_bytes_written() |
| 182 << " fin " << stream->fin_sent() << " count " | 184 << " fin " << stream->fin_sent() << " count " |
| 183 << stream->busy_counter(); | 185 << stream->busy_counter(); |
| 184 // Wait a few iterations before firing, the exact count is | 186 // Wait a few iterations before firing, the exact count is |
| 185 // arbitrary, more than a few to cover a few test-only false | 187 // arbitrary, more than a few to cover a few test-only false |
| 186 // positives. | 188 // positives. |
| 187 if (stream->busy_counter() > 20) { | 189 if (stream->busy_counter() > 20) { |
| 188 LOG(ERROR) << "Detected busy loop on stream id " << stream->id() | 190 QUIC_LOG(ERROR) << "Detected busy loop on stream id " << stream->id() |
| 189 << " stream_bytes_written " << stream->stream_bytes_written() | 191 << " stream_bytes_written " |
| 190 << " fin " << stream->fin_sent(); | 192 << stream->stream_bytes_written() << " fin " |
| 193 << stream->fin_sent(); |
| 191 return false; | 194 return false; |
| 192 } | 195 } |
| 193 } else { | 196 } else { |
| 194 stream->set_busy_counter(0); | 197 stream->set_busy_counter(0); |
| 195 } | 198 } |
| 196 return true; | 199 return true; |
| 197 } | 200 } |
| 198 | 201 |
| 199 void QuicSession::OnCanWrite() { | 202 void QuicSession::OnCanWrite() { |
| 200 // We limit the number of writes to the number of pending streams. If more | 203 // We limit the number of writes to the number of pending streams. If more |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 if (!connection_->CanWriteStreamData()) { | 236 if (!connection_->CanWriteStreamData()) { |
| 234 return; | 237 return; |
| 235 } | 238 } |
| 236 currently_writing_stream_id_ = write_blocked_streams_.PopFront(); | 239 currently_writing_stream_id_ = write_blocked_streams_.PopFront(); |
| 237 QuicStream* stream = GetOrCreateStream(currently_writing_stream_id_); | 240 QuicStream* stream = GetOrCreateStream(currently_writing_stream_id_); |
| 238 if (stream != nullptr && !stream->flow_controller()->IsBlocked()) { | 241 if (stream != nullptr && !stream->flow_controller()->IsBlocked()) { |
| 239 // If the stream can't write all bytes it'll re-add itself to the blocked | 242 // If the stream can't write all bytes it'll re-add itself to the blocked |
| 240 // list. | 243 // list. |
| 241 uint64_t previous_bytes_written = stream->stream_bytes_written(); | 244 uint64_t previous_bytes_written = stream->stream_bytes_written(); |
| 242 bool previous_fin_sent = stream->fin_sent(); | 245 bool previous_fin_sent = stream->fin_sent(); |
| 243 DVLOG(1) << "stream " << stream->id() << " bytes_written " | 246 QUIC_DVLOG(1) << "stream " << stream->id() << " bytes_written " |
| 244 << previous_bytes_written << " fin " << previous_fin_sent; | 247 << previous_bytes_written << " fin " << previous_fin_sent; |
| 245 stream->OnCanWrite(); | 248 stream->OnCanWrite(); |
| 246 DCHECK(CheckStreamNotBusyLooping(stream, previous_bytes_written, | 249 DCHECK(CheckStreamNotBusyLooping(stream, previous_bytes_written, |
| 247 previous_fin_sent)); | 250 previous_fin_sent)); |
| 248 } | 251 } |
| 249 currently_writing_stream_id_ = 0; | 252 currently_writing_stream_id_ = 0; |
| 250 } | 253 } |
| 251 } | 254 } |
| 252 | 255 |
| 253 bool QuicSession::WillingAndAbleToWrite() const { | 256 bool QuicSession::WillingAndAbleToWrite() const { |
| 254 // If the crypto or headers streams are blocked, we want to schedule a write - | 257 // If the crypto or headers streams are blocked, we want to schedule a write - |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 void QuicSession::InsertLocallyClosedStreamsHighestOffset( | 339 void QuicSession::InsertLocallyClosedStreamsHighestOffset( |
| 337 const QuicStreamId id, | 340 const QuicStreamId id, |
| 338 QuicStreamOffset offset) { | 341 QuicStreamOffset offset) { |
| 339 locally_closed_streams_highest_offset_[id] = offset; | 342 locally_closed_streams_highest_offset_[id] = offset; |
| 340 if (IsIncomingStream(id)) { | 343 if (IsIncomingStream(id)) { |
| 341 ++num_locally_closed_incoming_streams_highest_offset_; | 344 ++num_locally_closed_incoming_streams_highest_offset_; |
| 342 } | 345 } |
| 343 } | 346 } |
| 344 | 347 |
| 345 void QuicSession::CloseStreamInner(QuicStreamId stream_id, bool locally_reset) { | 348 void QuicSession::CloseStreamInner(QuicStreamId stream_id, bool locally_reset) { |
| 346 DVLOG(1) << ENDPOINT << "Closing stream " << stream_id; | 349 QUIC_DLOG(INFO) << ENDPOINT << "Closing stream " << stream_id; |
| 347 | 350 |
| 348 DynamicStreamMap::iterator it = dynamic_stream_map_.find(stream_id); | 351 DynamicStreamMap::iterator it = dynamic_stream_map_.find(stream_id); |
| 349 if (it == dynamic_stream_map_.end()) { | 352 if (it == dynamic_stream_map_.end()) { |
| 350 // When CloseStreamInner has been called recursively (via | 353 // When CloseStreamInner has been called recursively (via |
| 351 // QuicStream::OnClose), the stream will already have been deleted | 354 // QuicStream::OnClose), the stream will already have been deleted |
| 352 // from stream_map_, so return immediately. | 355 // from stream_map_, so return immediately. |
| 353 DVLOG(1) << ENDPOINT << "Stream is already closed: " << stream_id; | 356 QUIC_DLOG(INFO) << ENDPOINT << "Stream is already closed: " << stream_id; |
| 354 return; | 357 return; |
| 355 } | 358 } |
| 356 QuicStream* stream = it->second.get(); | 359 QuicStream* stream = it->second.get(); |
| 357 | 360 |
| 358 // Tell the stream that a RST has been sent. | 361 // Tell the stream that a RST has been sent. |
| 359 if (locally_reset) { | 362 if (locally_reset) { |
| 360 stream->set_rst_sent(true); | 363 stream->set_rst_sent(true); |
| 361 } | 364 } |
| 362 | 365 |
| 363 closed_streams_.push_back(std::move(it->second)); | 366 closed_streams_.push_back(std::move(it->second)); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 388 | 391 |
| 389 void QuicSession::UpdateFlowControlOnFinalReceivedByteOffset( | 392 void QuicSession::UpdateFlowControlOnFinalReceivedByteOffset( |
| 390 QuicStreamId stream_id, | 393 QuicStreamId stream_id, |
| 391 QuicStreamOffset final_byte_offset) { | 394 QuicStreamOffset final_byte_offset) { |
| 392 std::map<QuicStreamId, QuicStreamOffset>::iterator it = | 395 std::map<QuicStreamId, QuicStreamOffset>::iterator it = |
| 393 locally_closed_streams_highest_offset_.find(stream_id); | 396 locally_closed_streams_highest_offset_.find(stream_id); |
| 394 if (it == locally_closed_streams_highest_offset_.end()) { | 397 if (it == locally_closed_streams_highest_offset_.end()) { |
| 395 return; | 398 return; |
| 396 } | 399 } |
| 397 | 400 |
| 398 DVLOG(1) << ENDPOINT << "Received final byte offset " << final_byte_offset | 401 QUIC_DVLOG(1) << ENDPOINT << "Received final byte offset " |
| 399 << " for stream " << stream_id; | 402 << final_byte_offset << " for stream " << stream_id; |
| 400 QuicByteCount offset_diff = final_byte_offset - it->second; | 403 QuicByteCount offset_diff = final_byte_offset - it->second; |
| 401 if (flow_controller_.UpdateHighestReceivedOffset( | 404 if (flow_controller_.UpdateHighestReceivedOffset( |
| 402 flow_controller_.highest_received_byte_offset() + offset_diff)) { | 405 flow_controller_.highest_received_byte_offset() + offset_diff)) { |
| 403 // If the final offset violates flow control, close the connection now. | 406 // If the final offset violates flow control, close the connection now. |
| 404 if (flow_controller_.FlowControlViolation()) { | 407 if (flow_controller_.FlowControlViolation()) { |
| 405 connection_->CloseConnection( | 408 connection_->CloseConnection( |
| 406 QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, | 409 QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, |
| 407 "Connection level flow control violation", | 410 "Connection level flow control violation", |
| 408 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); | 411 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); |
| 409 return; | 412 return; |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 } | 496 } |
| 494 | 497 |
| 495 void QuicSession::AdjustInitialFlowControlWindows(size_t stream_window) { | 498 void QuicSession::AdjustInitialFlowControlWindows(size_t stream_window) { |
| 496 const float session_window_multiplier = | 499 const float session_window_multiplier = |
| 497 config_.GetInitialStreamFlowControlWindowToSend() | 500 config_.GetInitialStreamFlowControlWindowToSend() |
| 498 ? static_cast<float>( | 501 ? static_cast<float>( |
| 499 config_.GetInitialSessionFlowControlWindowToSend()) / | 502 config_.GetInitialSessionFlowControlWindowToSend()) / |
| 500 config_.GetInitialStreamFlowControlWindowToSend() | 503 config_.GetInitialStreamFlowControlWindowToSend() |
| 501 : 1.5; | 504 : 1.5; |
| 502 | 505 |
| 503 DVLOG(1) << ENDPOINT << "Set stream receive window to " << stream_window; | 506 QUIC_DVLOG(1) << ENDPOINT << "Set stream receive window to " << stream_window; |
| 504 config_.SetInitialStreamFlowControlWindowToSend(stream_window); | 507 config_.SetInitialStreamFlowControlWindowToSend(stream_window); |
| 505 | 508 |
| 506 size_t session_window = session_window_multiplier * stream_window; | 509 size_t session_window = session_window_multiplier * stream_window; |
| 507 DVLOG(1) << ENDPOINT << "Set session receive window to " << session_window; | 510 QUIC_DVLOG(1) << ENDPOINT << "Set session receive window to " |
| 511 << session_window; |
| 508 config_.SetInitialSessionFlowControlWindowToSend(session_window); | 512 config_.SetInitialSessionFlowControlWindowToSend(session_window); |
| 509 flow_controller_.UpdateReceiveWindowSize(session_window); | 513 flow_controller_.UpdateReceiveWindowSize(session_window); |
| 510 // Inform all existing streams about the new window. | 514 // Inform all existing streams about the new window. |
| 511 for (auto const& kv : static_stream_map_) { | 515 for (auto const& kv : static_stream_map_) { |
| 512 kv.second->flow_controller()->UpdateReceiveWindowSize(stream_window); | 516 kv.second->flow_controller()->UpdateReceiveWindowSize(stream_window); |
| 513 } | 517 } |
| 514 for (auto const& kv : dynamic_stream_map_) { | 518 for (auto const& kv : dynamic_stream_map_) { |
| 515 kv.second->flow_controller()->UpdateReceiveWindowSize(stream_window); | 519 kv.second->flow_controller()->UpdateReceiveWindowSize(stream_window); |
| 516 } | 520 } |
| 517 } | 521 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 534 if (IsClosedStream(frame.stream_id)) { | 538 if (IsClosedStream(frame.stream_id)) { |
| 535 // The RST frame contains the final byte offset for the stream: we can now | 539 // The RST frame contains the final byte offset for the stream: we can now |
| 536 // update the connection level flow controller if needed. | 540 // update the connection level flow controller if needed. |
| 537 UpdateFlowControlOnFinalReceivedByteOffset(frame.stream_id, | 541 UpdateFlowControlOnFinalReceivedByteOffset(frame.stream_id, |
| 538 frame.byte_offset); | 542 frame.byte_offset); |
| 539 } | 543 } |
| 540 } | 544 } |
| 541 | 545 |
| 542 void QuicSession::OnNewStreamFlowControlWindow(QuicStreamOffset new_window) { | 546 void QuicSession::OnNewStreamFlowControlWindow(QuicStreamOffset new_window) { |
| 543 if (new_window < kMinimumFlowControlSendWindow) { | 547 if (new_window < kMinimumFlowControlSendWindow) { |
| 544 LOG(ERROR) << "Peer sent us an invalid stream flow control send window: " | 548 QUIC_LOG_FIRST_N(ERROR, 1) |
| 545 << new_window | 549 << "Peer sent us an invalid stream flow control send window: " |
| 546 << ", below default: " << kMinimumFlowControlSendWindow; | 550 << new_window << ", below default: " << kMinimumFlowControlSendWindow; |
| 547 if (connection_->connected()) { | 551 if (connection_->connected()) { |
| 548 connection_->CloseConnection( | 552 connection_->CloseConnection( |
| 549 QUIC_FLOW_CONTROL_INVALID_WINDOW, "New stream window too low", | 553 QUIC_FLOW_CONTROL_INVALID_WINDOW, "New stream window too low", |
| 550 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); | 554 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); |
| 551 } | 555 } |
| 552 return; | 556 return; |
| 553 } | 557 } |
| 554 | 558 |
| 555 // Inform all existing streams about the new window. | 559 // Inform all existing streams about the new window. |
| 556 for (auto const& kv : static_stream_map_) { | 560 for (auto const& kv : static_stream_map_) { |
| 557 kv.second->UpdateSendWindowOffset(new_window); | 561 kv.second->UpdateSendWindowOffset(new_window); |
| 558 } | 562 } |
| 559 for (auto const& kv : dynamic_stream_map_) { | 563 for (auto const& kv : dynamic_stream_map_) { |
| 560 kv.second->UpdateSendWindowOffset(new_window); | 564 kv.second->UpdateSendWindowOffset(new_window); |
| 561 } | 565 } |
| 562 } | 566 } |
| 563 | 567 |
| 564 void QuicSession::OnNewSessionFlowControlWindow(QuicStreamOffset new_window) { | 568 void QuicSession::OnNewSessionFlowControlWindow(QuicStreamOffset new_window) { |
| 565 if (new_window < kMinimumFlowControlSendWindow) { | 569 if (new_window < kMinimumFlowControlSendWindow) { |
| 566 LOG(ERROR) << "Peer sent us an invalid session flow control send window: " | 570 QUIC_LOG_FIRST_N(ERROR, 1) |
| 567 << new_window | 571 << "Peer sent us an invalid session flow control send window: " |
| 568 << ", below default: " << kMinimumFlowControlSendWindow; | 572 << new_window << ", below default: " << kMinimumFlowControlSendWindow; |
| 569 if (connection_->connected()) { | 573 if (connection_->connected()) { |
| 570 connection_->CloseConnection( | 574 connection_->CloseConnection( |
| 571 QUIC_FLOW_CONTROL_INVALID_WINDOW, "New connection window too low", | 575 QUIC_FLOW_CONTROL_INVALID_WINDOW, "New connection window too low", |
| 572 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); | 576 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); |
| 573 } | 577 } |
| 574 return; | 578 return; |
| 575 } | 579 } |
| 576 | 580 |
| 577 flow_controller_.UpdateSendWindowOffset(new_window); | 581 flow_controller_.UpdateSendWindowOffset(new_window); |
| 578 } | 582 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 596 | 600 |
| 597 case HANDSHAKE_CONFIRMED: | 601 case HANDSHAKE_CONFIRMED: |
| 598 QUIC_BUG_IF(!config_.negotiated()) | 602 QUIC_BUG_IF(!config_.negotiated()) |
| 599 << ENDPOINT << "Handshake confirmed without parameter negotiation."; | 603 << ENDPOINT << "Handshake confirmed without parameter negotiation."; |
| 600 // Discard originally encrypted packets, since they can't be decrypted by | 604 // Discard originally encrypted packets, since they can't be decrypted by |
| 601 // the peer. | 605 // the peer. |
| 602 connection_->NeuterUnencryptedPackets(); | 606 connection_->NeuterUnencryptedPackets(); |
| 603 break; | 607 break; |
| 604 | 608 |
| 605 default: | 609 default: |
| 606 LOG(ERROR) << ENDPOINT << "Got unknown handshake event: " << event; | 610 QUIC_LOG(ERROR) << ENDPOINT << "Got unknown handshake event: " << event; |
| 607 } | 611 } |
| 608 } | 612 } |
| 609 | 613 |
| 610 void QuicSession::OnCryptoHandshakeMessageSent( | 614 void QuicSession::OnCryptoHandshakeMessageSent( |
| 611 const CryptoHandshakeMessage& /*message*/) {} | 615 const CryptoHandshakeMessage& /*message*/) {} |
| 612 | 616 |
| 613 void QuicSession::OnCryptoHandshakeMessageReceived( | 617 void QuicSession::OnCryptoHandshakeMessageReceived( |
| 614 const CryptoHandshakeMessage& /*message*/) {} | 618 const CryptoHandshakeMessage& /*message*/) {} |
| 615 | 619 |
| 616 QuicConfig* QuicSession::config() { | 620 QuicConfig* QuicSession::config() { |
| 617 return &config_; | 621 return &config_; |
| 618 } | 622 } |
| 619 | 623 |
| 620 void QuicSession::ActivateStream(std::unique_ptr<QuicStream> stream) { | 624 void QuicSession::ActivateStream(std::unique_ptr<QuicStream> stream) { |
| 621 QuicStreamId stream_id = stream->id(); | 625 QuicStreamId stream_id = stream->id(); |
| 622 DVLOG(1) << ENDPOINT << "num_streams: " << dynamic_stream_map_.size() | 626 QUIC_DLOG(INFO) << ENDPOINT << "num_streams: " << dynamic_stream_map_.size() |
| 623 << ". activating " << stream_id; | 627 << ". activating " << stream_id; |
| 624 DCHECK(!base::ContainsKey(dynamic_stream_map_, stream_id)); | 628 DCHECK(!base::ContainsKey(dynamic_stream_map_, stream_id)); |
| 625 DCHECK(!base::ContainsKey(static_stream_map_, stream_id)); | 629 DCHECK(!base::ContainsKey(static_stream_map_, stream_id)); |
| 626 dynamic_stream_map_[stream_id] = std::move(stream); | 630 dynamic_stream_map_[stream_id] = std::move(stream); |
| 627 if (IsIncomingStream(stream_id)) { | 631 if (IsIncomingStream(stream_id)) { |
| 628 ++num_dynamic_incoming_streams_; | 632 ++num_dynamic_incoming_streams_; |
| 629 } | 633 } |
| 630 // Increase the number of streams being emulated when a new one is opened. | 634 // Increase the number of streams being emulated when a new one is opened. |
| 631 connection_->SetNumOpenStreams(dynamic_stream_map_.size()); | 635 connection_->SetNumOpenStreams(dynamic_stream_map_.size()); |
| 632 } | 636 } |
| 633 | 637 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 662 } | 666 } |
| 663 | 667 |
| 664 // Check if the new number of available streams would cause the number of | 668 // Check if the new number of available streams would cause the number of |
| 665 // available streams to exceed the limit. Note that the peer can create | 669 // available streams to exceed the limit. Note that the peer can create |
| 666 // only alternately-numbered streams. | 670 // only alternately-numbered streams. |
| 667 size_t additional_available_streams = | 671 size_t additional_available_streams = |
| 668 (stream_id - largest_peer_created_stream_id_) / 2 - 1; | 672 (stream_id - largest_peer_created_stream_id_) / 2 - 1; |
| 669 size_t new_num_available_streams = | 673 size_t new_num_available_streams = |
| 670 GetNumAvailableStreams() + additional_available_streams; | 674 GetNumAvailableStreams() + additional_available_streams; |
| 671 if (new_num_available_streams > MaxAvailableStreams()) { | 675 if (new_num_available_streams > MaxAvailableStreams()) { |
| 672 DVLOG(1) << ENDPOINT | 676 QUIC_DLOG(INFO) << ENDPOINT |
| 673 << "Failed to create a new incoming stream with id:" << stream_id | 677 << "Failed to create a new incoming stream with id:" |
| 674 << ". There are already " << GetNumAvailableStreams() | 678 << stream_id << ". There are already " |
| 675 << " streams available, which would become " | 679 << GetNumAvailableStreams() |
| 676 << new_num_available_streams << ", which exceeds the limit " | 680 << " streams available, which would become " |
| 677 << MaxAvailableStreams() << "."; | 681 << new_num_available_streams << ", which exceeds the limit " |
| 682 << MaxAvailableStreams() << "."; |
| 678 connection()->CloseConnection( | 683 connection()->CloseConnection( |
| 679 QUIC_TOO_MANY_AVAILABLE_STREAMS, | 684 QUIC_TOO_MANY_AVAILABLE_STREAMS, |
| 680 QuicStrCat(new_num_available_streams, " above ", MaxAvailableStreams()), | 685 QuicStrCat(new_num_available_streams, " above ", MaxAvailableStreams()), |
| 681 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); | 686 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); |
| 682 return false; | 687 return false; |
| 683 } | 688 } |
| 684 for (QuicStreamId id = largest_peer_created_stream_id_ + 2; id < stream_id; | 689 for (QuicStreamId id = largest_peer_created_stream_id_ + 2; id < stream_id; |
| 685 id += 2) { | 690 id += 2) { |
| 686 available_streams_.insert(id); | 691 available_streams_.insert(id); |
| 687 } | 692 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 727 // Refuse to open the stream. | 732 // Refuse to open the stream. |
| 728 SendRstStream(stream_id, QUIC_REFUSED_STREAM, 0); | 733 SendRstStream(stream_id, QUIC_REFUSED_STREAM, 0); |
| 729 return nullptr; | 734 return nullptr; |
| 730 } | 735 } |
| 731 | 736 |
| 732 return CreateIncomingDynamicStream(stream_id); | 737 return CreateIncomingDynamicStream(stream_id); |
| 733 } | 738 } |
| 734 | 739 |
| 735 void QuicSession::set_max_open_incoming_streams( | 740 void QuicSession::set_max_open_incoming_streams( |
| 736 size_t max_open_incoming_streams) { | 741 size_t max_open_incoming_streams) { |
| 737 DVLOG(1) << "Setting max_open_incoming_streams_ to " | 742 QUIC_DVLOG(1) << "Setting max_open_incoming_streams_ to " |
| 738 << max_open_incoming_streams; | 743 << max_open_incoming_streams; |
| 739 max_open_incoming_streams_ = max_open_incoming_streams; | 744 max_open_incoming_streams_ = max_open_incoming_streams; |
| 740 DVLOG(1) << "MaxAvailableStreams() became " << MaxAvailableStreams(); | 745 QUIC_DVLOG(1) << "MaxAvailableStreams() became " << MaxAvailableStreams(); |
| 741 } | 746 } |
| 742 | 747 |
| 743 void QuicSession::set_max_open_outgoing_streams( | 748 void QuicSession::set_max_open_outgoing_streams( |
| 744 size_t max_open_outgoing_streams) { | 749 size_t max_open_outgoing_streams) { |
| 745 DVLOG(1) << "Setting max_open_outgoing_streams_ to " | 750 QUIC_DVLOG(1) << "Setting max_open_outgoing_streams_ to " |
| 746 << max_open_outgoing_streams; | 751 << max_open_outgoing_streams; |
| 747 max_open_outgoing_streams_ = max_open_outgoing_streams; | 752 max_open_outgoing_streams_ = max_open_outgoing_streams; |
| 748 } | 753 } |
| 749 | 754 |
| 750 bool QuicSession::goaway_sent() const { | 755 bool QuicSession::goaway_sent() const { |
| 751 return connection_->goaway_sent(); | 756 return connection_->goaway_sent(); |
| 752 } | 757 } |
| 753 | 758 |
| 754 bool QuicSession::goaway_received() const { | 759 bool QuicSession::goaway_received() const { |
| 755 return connection_->goaway_received(); | 760 return connection_->goaway_received(); |
| 756 } | 761 } |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 857 | 862 |
| 858 size_t QuicSession::MaxAvailableStreams() const { | 863 size_t QuicSession::MaxAvailableStreams() const { |
| 859 return max_open_incoming_streams_ * kMaxAvailableStreamsMultiplier; | 864 return max_open_incoming_streams_ * kMaxAvailableStreamsMultiplier; |
| 860 } | 865 } |
| 861 | 866 |
| 862 bool QuicSession::IsIncomingStream(QuicStreamId id) const { | 867 bool QuicSession::IsIncomingStream(QuicStreamId id) const { |
| 863 return id % 2 != next_outgoing_stream_id_ % 2; | 868 return id % 2 != next_outgoing_stream_id_ % 2; |
| 864 } | 869 } |
| 865 | 870 |
| 866 } // namespace net | 871 } // namespace net |
| OLD | NEW |