| 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_stream.h" | 5 #include "net/quic/core/quic_stream.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | |
| 8 #include "net/quic/core/quic_flags.h" | 7 #include "net/quic/core/quic_flags.h" |
| 9 #include "net/quic/core/quic_flow_controller.h" | 8 #include "net/quic/core/quic_flow_controller.h" |
| 10 #include "net/quic/core/quic_session.h" | 9 #include "net/quic/core/quic_session.h" |
| 11 #include "net/quic/core/quic_write_blocked_list.h" | 10 #include "net/quic/core/quic_write_blocked_list.h" |
| 12 #include "net/quic/platform/api/quic_bug_tracker.h" | 11 #include "net/quic/platform/api/quic_bug_tracker.h" |
| 12 #include "net/quic/platform/api/quic_logging.h" |
| 13 | 13 |
| 14 using base::StringPiece; | 14 using base::StringPiece; |
| 15 using std::string; | 15 using std::string; |
| 16 | 16 |
| 17 namespace net { | 17 namespace net { |
| 18 | 18 |
| 19 #define ENDPOINT \ | 19 #define ENDPOINT \ |
| 20 (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ") | 20 (perspective_ == Perspective::IS_SERVER ? "Server: " : "Client: ") |
| 21 | 21 |
| 22 namespace { | 22 namespace { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 DCHECK(!(read_side_closed_ && write_side_closed_)); | 89 DCHECK(!(read_side_closed_ && write_side_closed_)); |
| 90 | 90 |
| 91 if (frame.fin) { | 91 if (frame.fin) { |
| 92 fin_received_ = true; | 92 fin_received_ = true; |
| 93 if (fin_sent_) { | 93 if (fin_sent_) { |
| 94 session_->StreamDraining(id_); | 94 session_->StreamDraining(id_); |
| 95 } | 95 } |
| 96 } | 96 } |
| 97 | 97 |
| 98 if (read_side_closed_) { | 98 if (read_side_closed_) { |
| 99 DVLOG(1) << ENDPOINT << "Stream " << frame.stream_id | 99 QUIC_DLOG(INFO) |
| 100 << " is closed for reading. Ignoring newly received stream data."; | 100 << ENDPOINT << "Stream " << frame.stream_id |
| 101 << " is closed for reading. Ignoring newly received stream data."; |
| 101 // The subclass does not want to read data: blackhole the data. | 102 // The subclass does not want to read data: blackhole the data. |
| 102 return; | 103 return; |
| 103 } | 104 } |
| 104 | 105 |
| 105 // This count includes duplicate data received. | 106 // This count includes duplicate data received. |
| 106 size_t frame_payload_size = frame.data_length; | 107 size_t frame_payload_size = frame.data_length; |
| 107 stream_bytes_read_ += frame_payload_size; | 108 stream_bytes_read_ += frame_payload_size; |
| 108 | 109 |
| 109 // Flow control is interested in tracking highest received offset. | 110 // Flow control is interested in tracking highest received offset. |
| 110 // Only interested in received frames that carry data. | 111 // Only interested in received frames that carry data. |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 if (data.empty() && !fin) { | 187 if (data.empty() && !fin) { |
| 187 QUIC_BUG << "data.empty() && !fin"; | 188 QUIC_BUG << "data.empty() && !fin"; |
| 188 return; | 189 return; |
| 189 } | 190 } |
| 190 | 191 |
| 191 if (fin_buffered_) { | 192 if (fin_buffered_) { |
| 192 QUIC_BUG << "Fin already buffered"; | 193 QUIC_BUG << "Fin already buffered"; |
| 193 return; | 194 return; |
| 194 } | 195 } |
| 195 if (write_side_closed_) { | 196 if (write_side_closed_) { |
| 196 DLOG(ERROR) << ENDPOINT << "Attempt to write when the write side is closed"; | 197 QUIC_DLOG(ERROR) << ENDPOINT |
| 198 << "Attempt to write when the write side is closed"; |
| 197 return; | 199 return; |
| 198 } | 200 } |
| 199 | 201 |
| 200 QuicConsumedData consumed_data(0, false); | 202 QuicConsumedData consumed_data(0, false); |
| 201 fin_buffered_ = fin; | 203 fin_buffered_ = fin; |
| 202 | 204 |
| 203 if (queued_data_.empty()) { | 205 if (queued_data_.empty()) { |
| 204 struct iovec iov(MakeIovec(data)); | 206 struct iovec iov(MakeIovec(data)); |
| 205 consumed_data = WritevData(&iov, 1, fin, ack_listener); | 207 consumed_data = WritevData(&iov, 1, fin, ack_listener); |
| 206 DCHECK_LE(consumed_data.bytes_consumed, data.length()); | 208 DCHECK_LE(consumed_data.bytes_consumed, data.length()); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 session_->MarkConnectionLevelWriteBlocked(id()); | 267 session_->MarkConnectionLevelWriteBlocked(id()); |
| 266 } | 268 } |
| 267 } | 269 } |
| 268 | 270 |
| 269 QuicConsumedData QuicStream::WritevData( | 271 QuicConsumedData QuicStream::WritevData( |
| 270 const struct iovec* iov, | 272 const struct iovec* iov, |
| 271 int iov_count, | 273 int iov_count, |
| 272 bool fin, | 274 bool fin, |
| 273 QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) { | 275 QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) { |
| 274 if (write_side_closed_) { | 276 if (write_side_closed_) { |
| 275 DLOG(ERROR) << ENDPOINT << "Attempt to write when the write side is closed"; | 277 QUIC_DLOG(ERROR) << ENDPOINT |
| 278 << "Attempt to write when the write side is closed"; |
| 276 return QuicConsumedData(0, false); | 279 return QuicConsumedData(0, false); |
| 277 } | 280 } |
| 278 | 281 |
| 279 // How much data was provided. | 282 // How much data was provided. |
| 280 size_t write_length = 0; | 283 size_t write_length = 0; |
| 281 if (iov != nullptr) { | 284 if (iov != nullptr) { |
| 282 for (int i = 0; i < iov_count; ++i) { | 285 for (int i = 0; i < iov_count; ++i) { |
| 283 write_length += iov[i].iov_len; | 286 write_length += iov[i].iov_len; |
| 284 } | 287 } |
| 285 } | 288 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 304 MaybeSendBlocked(); | 307 MaybeSendBlocked(); |
| 305 return QuicConsumedData(0, false); | 308 return QuicConsumedData(0, false); |
| 306 } | 309 } |
| 307 | 310 |
| 308 if (write_length > send_window) { | 311 if (write_length > send_window) { |
| 309 // Don't send the FIN unless all the data will be sent. | 312 // Don't send the FIN unless all the data will be sent. |
| 310 fin = false; | 313 fin = false; |
| 311 | 314 |
| 312 // Writing more data would be a violation of flow control. | 315 // Writing more data would be a violation of flow control. |
| 313 write_length = static_cast<size_t>(send_window); | 316 write_length = static_cast<size_t>(send_window); |
| 314 DVLOG(1) << "stream " << id() << " shortens write length to " | 317 QUIC_DVLOG(1) << "stream " << id() << " shortens write length to " |
| 315 << write_length << " due to flow control"; | 318 << write_length << " due to flow control"; |
| 316 } | 319 } |
| 317 | 320 |
| 318 QuicConsumedData consumed_data = | 321 QuicConsumedData consumed_data = |
| 319 WritevDataInner(QuicIOVector(iov, iov_count, write_length), | 322 WritevDataInner(QuicIOVector(iov, iov_count, write_length), |
| 320 stream_bytes_written_, fin, std::move(ack_listener)); | 323 stream_bytes_written_, fin, std::move(ack_listener)); |
| 321 stream_bytes_written_ += consumed_data.bytes_consumed; | 324 stream_bytes_written_ += consumed_data.bytes_consumed; |
| 322 | 325 |
| 323 AddBytesSent(consumed_data.bytes_consumed); | 326 AddBytesSent(consumed_data.bytes_consumed); |
| 324 | 327 |
| 325 // The write may have generated a write error causing this stream to be | 328 // The write may have generated a write error causing this stream to be |
| (...skipping 27 matching lines...) Expand all Loading... |
| 353 bool fin, | 356 bool fin, |
| 354 QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) { | 357 QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) { |
| 355 return session()->WritevData(this, id(), iov, offset, fin, | 358 return session()->WritevData(this, id(), iov, offset, fin, |
| 356 std::move(ack_listener)); | 359 std::move(ack_listener)); |
| 357 } | 360 } |
| 358 | 361 |
| 359 void QuicStream::CloseReadSide() { | 362 void QuicStream::CloseReadSide() { |
| 360 if (read_side_closed_) { | 363 if (read_side_closed_) { |
| 361 return; | 364 return; |
| 362 } | 365 } |
| 363 DVLOG(1) << ENDPOINT << "Done reading from stream " << id(); | 366 QUIC_DLOG(INFO) << ENDPOINT << "Done reading from stream " << id(); |
| 364 | 367 |
| 365 read_side_closed_ = true; | 368 read_side_closed_ = true; |
| 366 sequencer_.ReleaseBuffer(); | 369 sequencer_.ReleaseBuffer(); |
| 367 | 370 |
| 368 if (write_side_closed_) { | 371 if (write_side_closed_) { |
| 369 DVLOG(1) << ENDPOINT << "Closing stream: " << id(); | 372 QUIC_DLOG(INFO) << ENDPOINT << "Closing stream: " << id(); |
| 370 session_->CloseStream(id()); | 373 session_->CloseStream(id()); |
| 371 } | 374 } |
| 372 } | 375 } |
| 373 | 376 |
| 374 void QuicStream::CloseWriteSide() { | 377 void QuicStream::CloseWriteSide() { |
| 375 if (write_side_closed_) { | 378 if (write_side_closed_) { |
| 376 return; | 379 return; |
| 377 } | 380 } |
| 378 DVLOG(1) << ENDPOINT << "Done writing to stream " << id(); | 381 QUIC_DLOG(INFO) << ENDPOINT << "Done writing to stream " << id(); |
| 379 | 382 |
| 380 write_side_closed_ = true; | 383 write_side_closed_ = true; |
| 381 if (read_side_closed_) { | 384 if (read_side_closed_) { |
| 382 DVLOG(1) << ENDPOINT << "Closing stream: " << id(); | 385 QUIC_DLOG(INFO) << ENDPOINT << "Closing stream: " << id(); |
| 383 session_->CloseStream(id()); | 386 session_->CloseStream(id()); |
| 384 } | 387 } |
| 385 } | 388 } |
| 386 | 389 |
| 387 bool QuicStream::HasBufferedData() const { | 390 bool QuicStream::HasBufferedData() const { |
| 388 return !queued_data_.empty(); | 391 return !queued_data_.empty(); |
| 389 } | 392 } |
| 390 | 393 |
| 391 QuicVersion QuicStream::version() const { | 394 QuicVersion QuicStream::version() const { |
| 392 return session_->connection()->version(); | 395 return session_->connection()->version(); |
| 393 } | 396 } |
| 394 | 397 |
| 395 void QuicStream::StopReading() { | 398 void QuicStream::StopReading() { |
| 396 DVLOG(1) << ENDPOINT << "Stop reading from stream " << id(); | 399 QUIC_DLOG(INFO) << ENDPOINT << "Stop reading from stream " << id(); |
| 397 sequencer_.StopReading(); | 400 sequencer_.StopReading(); |
| 398 } | 401 } |
| 399 | 402 |
| 400 const QuicSocketAddress& QuicStream::PeerAddressOfLatestPacket() const { | 403 const QuicSocketAddress& QuicStream::PeerAddressOfLatestPacket() const { |
| 401 return session_->connection()->last_packet_source_address(); | 404 return session_->connection()->last_packet_source_address(); |
| 402 } | 405 } |
| 403 | 406 |
| 404 void QuicStream::OnClose() { | 407 void QuicStream::OnClose() { |
| 405 CloseReadSide(); | 408 CloseReadSide(); |
| 406 CloseWriteSide(); | 409 CloseWriteSide(); |
| 407 | 410 |
| 408 if (!fin_sent_ && !rst_sent_) { | 411 if (!fin_sent_ && !rst_sent_) { |
| 409 // For flow control accounting, tell the peer how many bytes have been | 412 // For flow control accounting, tell the peer how many bytes have been |
| 410 // written on this stream before termination. Done here if needed, using a | 413 // written on this stream before termination. Done here if needed, using a |
| 411 // RST_STREAM frame. | 414 // RST_STREAM frame. |
| 412 DVLOG(1) << ENDPOINT << "Sending RST_STREAM in OnClose: " << id(); | 415 QUIC_DLOG(INFO) << ENDPOINT << "Sending RST_STREAM in OnClose: " << id(); |
| 413 session_->SendRstStream(id(), QUIC_RST_ACKNOWLEDGEMENT, | 416 session_->SendRstStream(id(), QUIC_RST_ACKNOWLEDGEMENT, |
| 414 stream_bytes_written_); | 417 stream_bytes_written_); |
| 415 rst_sent_ = true; | 418 rst_sent_ = true; |
| 416 } | 419 } |
| 417 | 420 |
| 418 // The stream is being closed and will not process any further incoming bytes. | 421 // The stream is being closed and will not process any further incoming bytes. |
| 419 // As there may be more bytes in flight, to ensure that both endpoints have | 422 // As there may be more bytes in flight, to ensure that both endpoints have |
| 420 // the same connection level flow control state, mark all unreceived or | 423 // the same connection level flow control state, mark all unreceived or |
| 421 // buffered bytes as consumed. | 424 // buffered bytes as consumed. |
| 422 QuicByteCount bytes_to_consume = | 425 QuicByteCount bytes_to_consume = |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 } | 476 } |
| 474 } | 477 } |
| 475 | 478 |
| 476 void QuicStream::UpdateSendWindowOffset(QuicStreamOffset new_window) { | 479 void QuicStream::UpdateSendWindowOffset(QuicStreamOffset new_window) { |
| 477 if (flow_controller_.UpdateSendWindowOffset(new_window)) { | 480 if (flow_controller_.UpdateSendWindowOffset(new_window)) { |
| 478 OnCanWrite(); | 481 OnCanWrite(); |
| 479 } | 482 } |
| 480 } | 483 } |
| 481 | 484 |
| 482 } // namespace net | 485 } // namespace net |
| OLD | NEW |