| 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/reliable_quic_stream.h" | 5 #include "net/quic/reliable_quic_stream.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "net/quic/iovector.h" | 8 #include "net/quic/iovector.h" |
| 9 #include "net/quic/quic_flow_controller.h" | 9 #include "net/quic/quic_flow_controller.h" |
| 10 #include "net/quic/quic_session.h" | 10 #include "net/quic/quic_session.h" |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 356 } | 356 } |
| 357 | 357 |
| 358 // How much data we want to write. | 358 // How much data we want to write. |
| 359 size_t write_length = TotalIovecLength(iov, iov_count); | 359 size_t write_length = TotalIovecLength(iov, iov_count); |
| 360 | 360 |
| 361 // A FIN with zero data payload should not be flow control blocked. | 361 // A FIN with zero data payload should not be flow control blocked. |
| 362 bool fin_with_zero_data = (fin && write_length == 0); | 362 bool fin_with_zero_data = (fin && write_length == 0); |
| 363 | 363 |
| 364 if (flow_controller_.IsEnabled()) { | 364 if (flow_controller_.IsEnabled()) { |
| 365 // How much data we are allowed to write from flow control. | 365 // How much data we are allowed to write from flow control. |
| 366 uint64 send_window = flow_controller_.SendWindowSize(); | 366 QuicByteCount send_window = flow_controller_.SendWindowSize(); |
| 367 // TODO(rjshade): Remove connection_flow_controller_->IsEnabled() check when | 367 // TODO(rjshade): Remove connection_flow_controller_->IsEnabled() check when |
| 368 // removing QUIC_VERSION_19. | 368 // removing QUIC_VERSION_19. |
| 369 if (stream_contributes_to_connection_flow_control_ && | 369 if (stream_contributes_to_connection_flow_control_ && |
| 370 connection_flow_controller_->IsEnabled()) { | 370 connection_flow_controller_->IsEnabled()) { |
| 371 send_window = | 371 send_window = |
| 372 min(send_window, connection_flow_controller_->SendWindowSize()); | 372 min(send_window, connection_flow_controller_->SendWindowSize()); |
| 373 } | 373 } |
| 374 | 374 |
| 375 if (send_window == 0 && !fin_with_zero_data) { | 375 if (send_window == 0 && !fin_with_zero_data) { |
| 376 // Quick return if we can't send anything. | 376 // Quick return if we can't send anything. |
| 377 MaybeSendBlocked(); | 377 MaybeSendBlocked(); |
| 378 return QuicConsumedData(0, false); | 378 return QuicConsumedData(0, false); |
| 379 } | 379 } |
| 380 | 380 |
| 381 if (write_length > send_window) { | 381 if (write_length > send_window) { |
| 382 // Don't send the FIN if we aren't going to send all the data. | 382 // Don't send the FIN if we aren't going to send all the data. |
| 383 fin = false; | 383 fin = false; |
| 384 | 384 |
| 385 // Writing more data would be a violation of flow control. | 385 // Writing more data would be a violation of flow control. |
| 386 write_length = send_window; | 386 write_length = static_cast<size_t>(send_window); |
| 387 } | 387 } |
| 388 } | 388 } |
| 389 | 389 |
| 390 // Fill an IOVector with bytes from the iovec. | 390 // Fill an IOVector with bytes from the iovec. |
| 391 IOVector data; | 391 IOVector data; |
| 392 data.AppendIovecAtMostBytes(iov, iov_count, write_length); | 392 data.AppendIovecAtMostBytes(iov, iov_count, write_length); |
| 393 | 393 |
| 394 QuicConsumedData consumed_data = session()->WritevData( | 394 QuicConsumedData consumed_data = session()->WritevData( |
| 395 id(), data, stream_bytes_written_, fin, GetFecProtection(), | 395 id(), data, stream_bytes_written_, fin, GetFecProtection(), |
| 396 ack_notifier_delegate); | 396 ack_notifier_delegate); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 DVLOG(1) << ENDPOINT << "Sending RST in OnClose: " << id(); | 459 DVLOG(1) << ENDPOINT << "Sending RST in OnClose: " << id(); |
| 460 session_->SendRstStream(id(), QUIC_RST_ACKNOWLEDGEMENT, | 460 session_->SendRstStream(id(), QUIC_RST_ACKNOWLEDGEMENT, |
| 461 stream_bytes_written_); | 461 stream_bytes_written_); |
| 462 rst_sent_ = true; | 462 rst_sent_ = true; |
| 463 } | 463 } |
| 464 | 464 |
| 465 // We are closing the stream and will not process any further incoming bytes. | 465 // We are closing the stream and will not process any further incoming bytes. |
| 466 // As there may be more bytes in flight and we need to ensure that both | 466 // As there may be more bytes in flight and we need to ensure that both |
| 467 // endpoints have the same connection level flow control state, mark all | 467 // endpoints have the same connection level flow control state, mark all |
| 468 // unreceived or buffered bytes as consumed. | 468 // unreceived or buffered bytes as consumed. |
| 469 uint64 bytes_to_consume = flow_controller_.highest_received_byte_offset() - | 469 QuicByteCount bytes_to_consume = |
| 470 flow_controller_.highest_received_byte_offset() - |
| 470 flow_controller_.bytes_consumed(); | 471 flow_controller_.bytes_consumed(); |
| 471 AddBytesConsumed(bytes_to_consume); | 472 AddBytesConsumed(bytes_to_consume); |
| 472 } | 473 } |
| 473 | 474 |
| 474 void ReliableQuicStream::OnWindowUpdateFrame( | 475 void ReliableQuicStream::OnWindowUpdateFrame( |
| 475 const QuicWindowUpdateFrame& frame) { | 476 const QuicWindowUpdateFrame& frame) { |
| 476 if (!flow_controller_.IsEnabled()) { | 477 if (!flow_controller_.IsEnabled()) { |
| 477 DLOG(DFATAL) << "Flow control not enabled! " << version(); | 478 DLOG(DFATAL) << "Flow control not enabled! " << version(); |
| 478 return; | 479 return; |
| 479 } | 480 } |
| 480 if (flow_controller_.UpdateSendWindowOffset(frame.byte_offset)) { | 481 if (flow_controller_.UpdateSendWindowOffset(frame.byte_offset)) { |
| 481 // We can write again! | 482 // We can write again! |
| 482 // TODO(rjshade): This does not respect priorities (e.g. multiple | 483 // TODO(rjshade): This does not respect priorities (e.g. multiple |
| 483 // outstanding POSTs are unblocked on arrival of | 484 // outstanding POSTs are unblocked on arrival of |
| 484 // SHLO with initial window). | 485 // SHLO with initial window). |
| 485 // As long as the connection is not flow control blocked, we can write! | 486 // As long as the connection is not flow control blocked, we can write! |
| 486 OnCanWrite(); | 487 OnCanWrite(); |
| 487 } | 488 } |
| 488 } | 489 } |
| 489 | 490 |
| 490 bool ReliableQuicStream::MaybeIncreaseHighestReceivedOffset(uint64 new_offset) { | 491 bool ReliableQuicStream::MaybeIncreaseHighestReceivedOffset( |
| 492 QuicStreamOffset new_offset) { |
| 491 if (!flow_controller_.IsEnabled()) { | 493 if (!flow_controller_.IsEnabled()) { |
| 492 return false; | 494 return false; |
| 493 } | 495 } |
| 494 uint64 increment = | 496 uint64 increment = |
| 495 new_offset - flow_controller_.highest_received_byte_offset(); | 497 new_offset - flow_controller_.highest_received_byte_offset(); |
| 496 if (!flow_controller_.UpdateHighestReceivedOffset(new_offset)) { | 498 if (!flow_controller_.UpdateHighestReceivedOffset(new_offset)) { |
| 497 return false; | 499 return false; |
| 498 } | 500 } |
| 499 | 501 |
| 500 // If |new_offset| increased the stream flow controller's highest received | 502 // If |new_offset| increased the stream flow controller's highest received |
| 501 // offset, then we need to increase the connection flow controller's value | 503 // offset, then we need to increase the connection flow controller's value |
| 502 // by the incremental difference. | 504 // by the incremental difference. |
| 503 if (stream_contributes_to_connection_flow_control_) { | 505 if (stream_contributes_to_connection_flow_control_) { |
| 504 connection_flow_controller_->UpdateHighestReceivedOffset( | 506 connection_flow_controller_->UpdateHighestReceivedOffset( |
| 505 connection_flow_controller_->highest_received_byte_offset() + | 507 connection_flow_controller_->highest_received_byte_offset() + |
| 506 increment); | 508 increment); |
| 507 } | 509 } |
| 508 return true; | 510 return true; |
| 509 } | 511 } |
| 510 | 512 |
| 511 void ReliableQuicStream::AddBytesSent(uint64 bytes) { | 513 void ReliableQuicStream::AddBytesSent(QuicByteCount bytes) { |
| 512 if (flow_controller_.IsEnabled()) { | 514 if (flow_controller_.IsEnabled()) { |
| 513 flow_controller_.AddBytesSent(bytes); | 515 flow_controller_.AddBytesSent(bytes); |
| 514 if (stream_contributes_to_connection_flow_control_) { | 516 if (stream_contributes_to_connection_flow_control_) { |
| 515 connection_flow_controller_->AddBytesSent(bytes); | 517 connection_flow_controller_->AddBytesSent(bytes); |
| 516 } | 518 } |
| 517 } | 519 } |
| 518 } | 520 } |
| 519 | 521 |
| 520 void ReliableQuicStream::AddBytesConsumed(uint64 bytes) { | 522 void ReliableQuicStream::AddBytesConsumed(QuicByteCount bytes) { |
| 521 if (flow_controller_.IsEnabled()) { | 523 if (flow_controller_.IsEnabled()) { |
| 522 // Only adjust stream level flow controller if we are still reading. | 524 // Only adjust stream level flow controller if we are still reading. |
| 523 if (!read_side_closed_) { | 525 if (!read_side_closed_) { |
| 524 flow_controller_.AddBytesConsumed(bytes); | 526 flow_controller_.AddBytesConsumed(bytes); |
| 525 } | 527 } |
| 526 | 528 |
| 527 if (stream_contributes_to_connection_flow_control_) { | 529 if (stream_contributes_to_connection_flow_control_) { |
| 528 connection_flow_controller_->AddBytesConsumed(bytes); | 530 connection_flow_controller_->AddBytesConsumed(bytes); |
| 529 } | 531 } |
| 530 } | 532 } |
| 531 } | 533 } |
| 532 | 534 |
| 533 void ReliableQuicStream::UpdateSendWindowOffset(uint64 new_window) { | 535 void ReliableQuicStream::UpdateSendWindowOffset(QuicStreamOffset new_window) { |
| 534 if (flow_controller_.UpdateSendWindowOffset(new_window)) { | 536 if (flow_controller_.UpdateSendWindowOffset(new_window)) { |
| 535 OnCanWrite(); | 537 OnCanWrite(); |
| 536 } | 538 } |
| 537 } | 539 } |
| 538 | 540 |
| 539 bool ReliableQuicStream::IsFlowControlBlocked() { | 541 bool ReliableQuicStream::IsFlowControlBlocked() { |
| 540 if (flow_controller_.IsBlocked()) { | 542 if (flow_controller_.IsBlocked()) { |
| 541 return true; | 543 return true; |
| 542 } | 544 } |
| 543 return stream_contributes_to_connection_flow_control_ && | 545 return stream_contributes_to_connection_flow_control_ && |
| 544 connection_flow_controller_->IsBlocked(); | 546 connection_flow_controller_->IsBlocked(); |
| 545 } | 547 } |
| 546 | 548 |
| 547 } // namespace net | 549 } // namespace net |
| OLD | NEW |