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

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

Issue 2487613002: Landing Recent QUIC changes until 12:43 PM, Nov 5, 2016 UTC+8 (Closed)
Patch Set: Created 4 years, 1 month 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/core/quic_session.h ('k') | net/quic/core/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/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 "base/strings/string_number_conversions.h" 9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/stringprintf.h" 10 #include "base/strings/stringprintf.h"
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 DLOG_IF(WARNING, GetNumLocallyClosedOutgoingStreamsHighestOffset() > 67 DLOG_IF(WARNING, GetNumLocallyClosedOutgoingStreamsHighestOffset() >
68 max_open_outgoing_streams_) 68 max_open_outgoing_streams_)
69 << "Surprisingly high number of locally closed self initiated streams" 69 << "Surprisingly high number of locally closed self initiated streams"
70 "still waiting for final byte offset: " 70 "still waiting for final byte offset: "
71 << GetNumLocallyClosedOutgoingStreamsHighestOffset(); 71 << GetNumLocallyClosedOutgoingStreamsHighestOffset();
72 } 72 }
73 73
74 void QuicSession::OnStreamFrame(const QuicStreamFrame& frame) { 74 void QuicSession::OnStreamFrame(const QuicStreamFrame& frame) {
75 // TODO(rch) deal with the error case of stream id 0. 75 // TODO(rch) deal with the error case of stream id 0.
76 QuicStreamId stream_id = frame.stream_id; 76 QuicStreamId stream_id = frame.stream_id;
77 ReliableQuicStream* stream = GetOrCreateStream(stream_id); 77 QuicStream* stream = GetOrCreateStream(stream_id);
78 if (!stream) { 78 if (!stream) {
79 // The stream no longer exists, but we may still be interested in the 79 // The stream no longer exists, but we may still be interested in the
80 // final stream byte offset sent by the peer. A frame with a FIN can give 80 // final stream byte offset sent by the peer. A frame with a FIN can give
81 // us this offset. 81 // us this offset.
82 if (frame.fin) { 82 if (frame.fin) {
83 QuicStreamOffset final_byte_offset = frame.offset + frame.data_length; 83 QuicStreamOffset final_byte_offset = frame.offset + frame.data_length;
84 UpdateFlowControlOnFinalReceivedByteOffset(stream_id, final_byte_offset); 84 UpdateFlowControlOnFinalReceivedByteOffset(stream_id, final_byte_offset);
85 } 85 }
86 return; 86 return;
87 } 87 }
88 stream->OnStreamFrame(frame); 88 stream->OnStreamFrame(frame);
89 } 89 }
90 90
91 void QuicSession::OnRstStream(const QuicRstStreamFrame& frame) { 91 void QuicSession::OnRstStream(const QuicRstStreamFrame& frame) {
92 if (base::ContainsKey(static_stream_map_, frame.stream_id)) { 92 if (base::ContainsKey(static_stream_map_, frame.stream_id)) {
93 connection()->CloseConnection( 93 connection()->CloseConnection(
94 QUIC_INVALID_STREAM_ID, "Attempt to reset a static stream", 94 QUIC_INVALID_STREAM_ID, "Attempt to reset a static stream",
95 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); 95 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
96 return; 96 return;
97 } 97 }
98 98
99 ReliableQuicStream* stream = GetOrCreateDynamicStream(frame.stream_id); 99 QuicStream* stream = GetOrCreateDynamicStream(frame.stream_id);
100 if (!stream) { 100 if (!stream) {
101 HandleRstOnValidNonexistentStream(frame); 101 HandleRstOnValidNonexistentStream(frame);
102 return; // Errors are handled by GetOrCreateStream. 102 return; // Errors are handled by GetOrCreateStream.
103 } 103 }
104 104
105 stream->OnStreamReset(frame); 105 stream->OnStreamReset(frame);
106 } 106 }
107 107
108 void QuicSession::OnGoAway(const QuicGoAwayFrame& frame) { 108 void QuicSession::OnGoAway(const QuicGoAwayFrame& frame) {
109 DCHECK(frame.last_good_stream_id < next_outgoing_stream_id_); 109 DCHECK(frame.last_good_stream_id < next_outgoing_stream_id_);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 QuicStreamId stream_id = frame.stream_id; 151 QuicStreamId stream_id = frame.stream_id;
152 if (stream_id == kConnectionLevelId) { 152 if (stream_id == kConnectionLevelId) {
153 // This is a window update that applies to the connection, rather than an 153 // This is a window update that applies to the connection, rather than an
154 // individual stream. 154 // individual stream.
155 DVLOG(1) << ENDPOINT << "Received connection level flow control window " 155 DVLOG(1) << ENDPOINT << "Received connection level flow control window "
156 "update with byte offset: " 156 "update with byte offset: "
157 << frame.byte_offset; 157 << frame.byte_offset;
158 flow_controller_.UpdateSendWindowOffset(frame.byte_offset); 158 flow_controller_.UpdateSendWindowOffset(frame.byte_offset);
159 return; 159 return;
160 } 160 }
161 ReliableQuicStream* stream = GetOrCreateStream(stream_id); 161 QuicStream* stream = GetOrCreateStream(stream_id);
162 if (stream != nullptr) { 162 if (stream != nullptr) {
163 stream->OnWindowUpdateFrame(frame); 163 stream->OnWindowUpdateFrame(frame);
164 } 164 }
165 } 165 }
166 166
167 void QuicSession::OnBlockedFrame(const QuicBlockedFrame& frame) { 167 void QuicSession::OnBlockedFrame(const QuicBlockedFrame& frame) {
168 // TODO(rjshade): Compare our flow control receive windows for specified 168 // TODO(rjshade): Compare our flow control receive windows for specified
169 // streams: if we have a large window then maybe something 169 // streams: if we have a large window then maybe something
170 // had gone wrong with the flow control accounting. 170 // had gone wrong with the flow control accounting.
171 DVLOG(1) << ENDPOINT 171 DVLOG(1) << ENDPOINT
172 << "Received BLOCKED frame with stream id: " << frame.stream_id; 172 << "Received BLOCKED frame with stream id: " << frame.stream_id;
173 } 173 }
174 174
175 bool QuicSession::CheckStreamNotBusyLooping(ReliableQuicStream* stream, 175 bool QuicSession::CheckStreamNotBusyLooping(QuicStream* stream,
176 uint64_t previous_bytes_written, 176 uint64_t previous_bytes_written,
177 bool previous_fin_sent) { 177 bool previous_fin_sent) {
178 if ( // Stream should not be closed. 178 if ( // Stream should not be closed.
179 !stream->write_side_closed() && 179 !stream->write_side_closed() &&
180 // Not connection flow control blocked. 180 // Not connection flow control blocked.
181 !flow_controller_.IsBlocked() && 181 !flow_controller_.IsBlocked() &&
182 // Detect lack of forward progress. 182 // Detect lack of forward progress.
183 previous_bytes_written == stream->stream_bytes_written() && 183 previous_bytes_written == stream->stream_bytes_written() &&
184 previous_fin_sent == stream->fin_sent()) { 184 previous_fin_sent == stream->fin_sent()) {
185 stream->set_busy_counter(stream->busy_counter() + 1); 185 stream->set_busy_counter(stream->busy_counter() + 1);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 QUIC_BUG << "WriteBlockedStream is missing"; 233 QUIC_BUG << "WriteBlockedStream is missing";
234 connection_->CloseConnection(QUIC_INTERNAL_ERROR, 234 connection_->CloseConnection(QUIC_INTERNAL_ERROR,
235 "WriteBlockedStream is missing", 235 "WriteBlockedStream is missing",
236 ConnectionCloseBehavior::SILENT_CLOSE); 236 ConnectionCloseBehavior::SILENT_CLOSE);
237 return; 237 return;
238 } 238 }
239 if (!connection_->CanWriteStreamData()) { 239 if (!connection_->CanWriteStreamData()) {
240 return; 240 return;
241 } 241 }
242 currently_writing_stream_id_ = write_blocked_streams_.PopFront(); 242 currently_writing_stream_id_ = write_blocked_streams_.PopFront();
243 ReliableQuicStream* stream = 243 QuicStream* stream = GetOrCreateStream(currently_writing_stream_id_);
244 GetOrCreateStream(currently_writing_stream_id_);
245 if (stream != nullptr && !stream->flow_controller()->IsBlocked()) { 244 if (stream != nullptr && !stream->flow_controller()->IsBlocked()) {
246 // If the stream can't write all bytes it'll re-add itself to the blocked 245 // If the stream can't write all bytes it'll re-add itself to the blocked
247 // list. 246 // list.
248 uint64_t previous_bytes_written = stream->stream_bytes_written(); 247 uint64_t previous_bytes_written = stream->stream_bytes_written();
249 bool previous_fin_sent = stream->fin_sent(); 248 bool previous_fin_sent = stream->fin_sent();
250 DVLOG(1) << "stream " << stream->id() << " bytes_written " 249 DVLOG(1) << "stream " << stream->id() << " bytes_written "
251 << previous_bytes_written << " fin " << previous_fin_sent; 250 << previous_bytes_written << " fin " << previous_fin_sent;
252 stream->OnCanWrite(); 251 stream->OnCanWrite();
253 DCHECK(CheckStreamNotBusyLooping(stream, previous_bytes_written, 252 DCHECK(CheckStreamNotBusyLooping(stream, previous_bytes_written,
254 previous_fin_sent)); 253 previous_fin_sent));
(...skipping 21 matching lines...) Expand all
276 locally_closed_streams_highest_offset_.size()) > 0; 275 locally_closed_streams_highest_offset_.size()) > 0;
277 } 276 }
278 277
279 void QuicSession::ProcessUdpPacket(const IPEndPoint& self_address, 278 void QuicSession::ProcessUdpPacket(const IPEndPoint& self_address,
280 const IPEndPoint& peer_address, 279 const IPEndPoint& peer_address,
281 const QuicReceivedPacket& packet) { 280 const QuicReceivedPacket& packet) {
282 connection_->ProcessUdpPacket(self_address, peer_address, packet); 281 connection_->ProcessUdpPacket(self_address, peer_address, packet);
283 } 282 }
284 283
285 QuicConsumedData QuicSession::WritevData( 284 QuicConsumedData QuicSession::WritevData(
286 ReliableQuicStream* stream, 285 QuicStream* stream,
287 QuicStreamId id, 286 QuicStreamId id,
288 QuicIOVector iov, 287 QuicIOVector iov,
289 QuicStreamOffset offset, 288 QuicStreamOffset offset,
290 bool fin, 289 bool fin,
291 QuicAckListenerInterface* ack_notifier_delegate) { 290 QuicAckListenerInterface* ack_notifier_delegate) {
292 // This check is an attempt to deal with potential memory corruption 291 // This check is an attempt to deal with potential memory corruption
293 // in which |id| ends up set to 1 (the crypto stream id). If this happen 292 // in which |id| ends up set to 1 (the crypto stream id). If this happen
294 // it might end up resulting in unencrypted stream data being sent. 293 // it might end up resulting in unencrypted stream data being sent.
295 // While this is impossible to avoid given sufficient corruption, this 294 // While this is impossible to avoid given sufficient corruption, this
296 // seems like a reasonable mitigation. 295 // seems like a reasonable mitigation.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 ++num_locally_closed_incoming_streams_highest_offset_; 347 ++num_locally_closed_incoming_streams_highest_offset_;
349 } 348 }
350 } 349 }
351 350
352 void QuicSession::CloseStreamInner(QuicStreamId stream_id, bool locally_reset) { 351 void QuicSession::CloseStreamInner(QuicStreamId stream_id, bool locally_reset) {
353 DVLOG(1) << ENDPOINT << "Closing stream " << stream_id; 352 DVLOG(1) << ENDPOINT << "Closing stream " << stream_id;
354 353
355 DynamicStreamMap::iterator it = dynamic_stream_map_.find(stream_id); 354 DynamicStreamMap::iterator it = dynamic_stream_map_.find(stream_id);
356 if (it == dynamic_stream_map_.end()) { 355 if (it == dynamic_stream_map_.end()) {
357 // When CloseStreamInner has been called recursively (via 356 // When CloseStreamInner has been called recursively (via
358 // ReliableQuicStream::OnClose), the stream will already have been deleted 357 // QuicStream::OnClose), the stream will already have been deleted
359 // from stream_map_, so return immediately. 358 // from stream_map_, so return immediately.
360 DVLOG(1) << ENDPOINT << "Stream is already closed: " << stream_id; 359 DVLOG(1) << ENDPOINT << "Stream is already closed: " << stream_id;
361 return; 360 return;
362 } 361 }
363 ReliableQuicStream* stream = it->second.get(); 362 QuicStream* stream = it->second.get();
364 363
365 // Tell the stream that a RST has been sent. 364 // Tell the stream that a RST has been sent.
366 if (locally_reset) { 365 if (locally_reset) {
367 stream->set_rst_sent(true); 366 stream->set_rst_sent(true);
368 } 367 }
369 368
370 closed_streams_.push_back(std::move(it->second)); 369 closed_streams_.push_back(std::move(it->second));
371 370
372 // If we haven't received a FIN or RST for this stream, we need to keep track 371 // If we haven't received a FIN or RST for this stream, we need to keep track
373 // of the how many bytes the stream's flow controller believes it has 372 // of the how many bytes the stream's flow controller believes it has
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 void QuicSession::OnCryptoHandshakeMessageSent( 570 void QuicSession::OnCryptoHandshakeMessageSent(
572 const CryptoHandshakeMessage& /*message*/) {} 571 const CryptoHandshakeMessage& /*message*/) {}
573 572
574 void QuicSession::OnCryptoHandshakeMessageReceived( 573 void QuicSession::OnCryptoHandshakeMessageReceived(
575 const CryptoHandshakeMessage& /*message*/) {} 574 const CryptoHandshakeMessage& /*message*/) {}
576 575
577 QuicConfig* QuicSession::config() { 576 QuicConfig* QuicSession::config() {
578 return &config_; 577 return &config_;
579 } 578 }
580 579
581 void QuicSession::ActivateStream(std::unique_ptr<ReliableQuicStream> stream) { 580 void QuicSession::ActivateStream(std::unique_ptr<QuicStream> stream) {
582 QuicStreamId stream_id = stream->id(); 581 QuicStreamId stream_id = stream->id();
583 DVLOG(1) << ENDPOINT << "num_streams: " << dynamic_stream_map_.size() 582 DVLOG(1) << ENDPOINT << "num_streams: " << dynamic_stream_map_.size()
584 << ". activating " << stream_id; 583 << ". activating " << stream_id;
585 DCHECK(!base::ContainsKey(dynamic_stream_map_, stream_id)); 584 DCHECK(!base::ContainsKey(dynamic_stream_map_, stream_id));
586 DCHECK(!base::ContainsKey(static_stream_map_, stream_id)); 585 DCHECK(!base::ContainsKey(static_stream_map_, stream_id));
587 dynamic_stream_map_[stream_id] = std::move(stream); 586 dynamic_stream_map_[stream_id] = std::move(stream);
588 if (IsIncomingStream(stream_id)) { 587 if (IsIncomingStream(stream_id)) {
589 ++num_dynamic_incoming_streams_; 588 ++num_dynamic_incoming_streams_;
590 } 589 }
591 // Increase the number of streams being emulated when a new one is opened. 590 // Increase the number of streams being emulated when a new one is opened.
592 connection_->SetNumOpenStreams(dynamic_stream_map_.size()); 591 connection_->SetNumOpenStreams(dynamic_stream_map_.size());
593 } 592 }
594 593
595 QuicStreamId QuicSession::GetNextOutgoingStreamId() { 594 QuicStreamId QuicSession::GetNextOutgoingStreamId() {
596 QuicStreamId id = next_outgoing_stream_id_; 595 QuicStreamId id = next_outgoing_stream_id_;
597 next_outgoing_stream_id_ += 2; 596 next_outgoing_stream_id_ += 2;
598 return id; 597 return id;
599 } 598 }
600 599
601 ReliableQuicStream* QuicSession::GetOrCreateStream( 600 QuicStream* QuicSession::GetOrCreateStream(const QuicStreamId stream_id) {
602 const QuicStreamId stream_id) {
603 StaticStreamMap::iterator it = static_stream_map_.find(stream_id); 601 StaticStreamMap::iterator it = static_stream_map_.find(stream_id);
604 if (it != static_stream_map_.end()) { 602 if (it != static_stream_map_.end()) {
605 return it->second; 603 return it->second;
606 } 604 }
607 return GetOrCreateDynamicStream(stream_id); 605 return GetOrCreateDynamicStream(stream_id);
608 } 606 }
609 607
610 void QuicSession::StreamDraining(QuicStreamId stream_id) { 608 void QuicSession::StreamDraining(QuicStreamId stream_id) {
611 DCHECK(base::ContainsKey(dynamic_stream_map_, stream_id)); 609 DCHECK(base::ContainsKey(dynamic_stream_map_, stream_id));
612 if (!base::ContainsKey(draining_streams_, stream_id)) { 610 if (!base::ContainsKey(draining_streams_, stream_id)) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 return true; 651 return true;
654 } 652 }
655 653
656 bool QuicSession::ShouldYield(QuicStreamId stream_id) { 654 bool QuicSession::ShouldYield(QuicStreamId stream_id) {
657 if (stream_id == currently_writing_stream_id_) { 655 if (stream_id == currently_writing_stream_id_) {
658 return false; 656 return false;
659 } 657 }
660 return write_blocked_streams()->ShouldYield(stream_id); 658 return write_blocked_streams()->ShouldYield(stream_id);
661 } 659 }
662 660
663 ReliableQuicStream* QuicSession::GetOrCreateDynamicStream( 661 QuicStream* QuicSession::GetOrCreateDynamicStream(
664 const QuicStreamId stream_id) { 662 const QuicStreamId stream_id) {
665 DCHECK(!base::ContainsKey(static_stream_map_, stream_id)) 663 DCHECK(!base::ContainsKey(static_stream_map_, stream_id))
666 << "Attempt to call GetOrCreateDynamicStream for a static stream"; 664 << "Attempt to call GetOrCreateDynamicStream for a static stream";
667 665
668 DynamicStreamMap::iterator it = dynamic_stream_map_.find(stream_id); 666 DynamicStreamMap::iterator it = dynamic_stream_map_.find(stream_id);
669 if (it != dynamic_stream_map_.end()) { 667 if (it != dynamic_stream_map_.end()) {
670 return it->second.get(); 668 return it->second.get();
671 } 669 }
672 670
673 if (IsClosedStream(stream_id)) { 671 if (IsClosedStream(stream_id)) {
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 818
821 size_t QuicSession::MaxAvailableStreams() const { 819 size_t QuicSession::MaxAvailableStreams() const {
822 return max_open_incoming_streams_ * kMaxAvailableStreamsMultiplier; 820 return max_open_incoming_streams_ * kMaxAvailableStreamsMultiplier;
823 } 821 }
824 822
825 bool QuicSession::IsIncomingStream(QuicStreamId id) const { 823 bool QuicSession::IsIncomingStream(QuicStreamId id) const {
826 return id % 2 != next_outgoing_stream_id_ % 2; 824 return id % 2 != next_outgoing_stream_id_ % 2;
827 } 825 }
828 826
829 } // namespace net 827 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/core/quic_session.h ('k') | net/quic/core/quic_session_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698