| 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/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" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 // To avoid deleting a stream in mid-operation, we have a simple shim between | 28 // To avoid deleting a stream in mid-operation, we have a simple shim between |
| 29 // us and the stream, so we can delete any streams when we return from | 29 // us and the stream, so we can delete any streams when we return from |
| 30 // processing. | 30 // processing. |
| 31 // | 31 // |
| 32 // We could just override the base methods, but this makes it easier to make | 32 // We could just override the base methods, but this makes it easier to make |
| 33 // sure we don't miss any. | 33 // sure we don't miss any. |
| 34 class VisitorShim : public QuicConnectionVisitorInterface { | 34 class VisitorShim : public QuicConnectionVisitorInterface { |
| 35 public: | 35 public: |
| 36 explicit VisitorShim(QuicSession* session) : session_(session) {} | 36 explicit VisitorShim(QuicSession* session) : session_(session) {} |
| 37 | 37 |
| 38 void OnStreamFrames(const vector<QuicStreamFrame>& frames) override { | 38 void OnStreamFrame(const QuicStreamFrame& frame) override { |
| 39 session_->OnStreamFrames(frames); | 39 session_->OnStreamFrame(frame); |
| 40 session_->PostProcessAfterData(); | 40 session_->PostProcessAfterData(); |
| 41 } | 41 } |
| 42 void OnRstStream(const QuicRstStreamFrame& frame) override { | 42 void OnRstStream(const QuicRstStreamFrame& frame) override { |
| 43 session_->OnRstStream(frame); | 43 session_->OnRstStream(frame); |
| 44 session_->PostProcessAfterData(); | 44 session_->PostProcessAfterData(); |
| 45 } | 45 } |
| 46 | 46 |
| 47 void OnGoAway(const QuicGoAwayFrame& frame) override { | 47 void OnGoAway(const QuicGoAwayFrame& frame) override { |
| 48 session_->OnGoAway(frame); | 48 session_->OnGoAway(frame); |
| 49 session_->PostProcessAfterData(); | 49 session_->PostProcessAfterData(); |
| 50 } | 50 } |
| 51 | 51 |
| 52 void OnWindowUpdateFrames( | 52 void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override { |
| 53 const vector<QuicWindowUpdateFrame>& frames) override { | 53 session_->OnWindowUpdateFrame(frame); |
| 54 session_->OnWindowUpdateFrames(frames); | |
| 55 session_->PostProcessAfterData(); | 54 session_->PostProcessAfterData(); |
| 56 } | 55 } |
| 57 | 56 |
| 58 void OnBlockedFrames(const vector<QuicBlockedFrame>& frames) override { | 57 void OnBlockedFrame(const QuicBlockedFrame& frame) override { |
| 59 session_->OnBlockedFrames(frames); | 58 session_->OnBlockedFrame(frame); |
| 60 session_->PostProcessAfterData(); | 59 session_->PostProcessAfterData(); |
| 61 } | 60 } |
| 62 | 61 |
| 63 void OnCanWrite() override { | 62 void OnCanWrite() override { |
| 64 session_->OnCanWrite(); | 63 session_->OnCanWrite(); |
| 65 session_->PostProcessAfterData(); | 64 session_->PostProcessAfterData(); |
| 66 } | 65 } |
| 67 | 66 |
| 68 void OnCongestionWindowChange(QuicTime now) override { | 67 void OnCongestionWindowChange(QuicTime now) override { |
| 69 session_->OnCongestionWindowChange(now); | 68 session_->OnCongestionWindowChange(now); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 QuicSession::~QuicSession() { | 126 QuicSession::~QuicSession() { |
| 128 STLDeleteElements(&closed_streams_); | 127 STLDeleteElements(&closed_streams_); |
| 129 STLDeleteValues(&dynamic_stream_map_); | 128 STLDeleteValues(&dynamic_stream_map_); |
| 130 | 129 |
| 131 DLOG_IF(WARNING, | 130 DLOG_IF(WARNING, |
| 132 locally_closed_streams_highest_offset_.size() > max_open_streams_) | 131 locally_closed_streams_highest_offset_.size() > max_open_streams_) |
| 133 << "Surprisingly high number of locally closed streams still waiting for " | 132 << "Surprisingly high number of locally closed streams still waiting for " |
| 134 "final byte offset: " << locally_closed_streams_highest_offset_.size(); | 133 "final byte offset: " << locally_closed_streams_highest_offset_.size(); |
| 135 } | 134 } |
| 136 | 135 |
| 137 void QuicSession::OnStreamFrames(const vector<QuicStreamFrame>& frames) { | 136 void QuicSession::OnStreamFrame(const QuicStreamFrame& frame) { |
| 138 for (size_t i = 0; i < frames.size() && connection_->connected(); ++i) { | 137 // TODO(rch) deal with the error case of stream id 0. |
| 139 // TODO(rch) deal with the error case of stream id 0. | 138 QuicStreamId stream_id = frame.stream_id; |
| 140 const QuicStreamFrame& frame = frames[i]; | 139 ReliableQuicStream* stream = GetStream(stream_id); |
| 141 QuicStreamId stream_id = frame.stream_id; | 140 if (!stream) { |
| 142 ReliableQuicStream* stream = GetStream(stream_id); | 141 // The stream no longer exists, but we may still be interested in the |
| 143 if (!stream) { | 142 // final stream byte offset sent by the peer. A frame with a FIN can give |
| 144 // The stream no longer exists, but we may still be interested in the | 143 // us this offset. |
| 145 // final stream byte offset sent by the peer. A frame with a FIN can give | 144 if (frame.fin) { |
| 146 // us this offset. | 145 QuicStreamOffset final_byte_offset = frame.offset + frame.data.size(); |
| 147 if (frame.fin) { | 146 UpdateFlowControlOnFinalReceivedByteOffset(stream_id, final_byte_offset); |
| 148 QuicStreamOffset final_byte_offset = frame.offset + frame.data.size(); | |
| 149 UpdateFlowControlOnFinalReceivedByteOffset(stream_id, | |
| 150 final_byte_offset); | |
| 151 } | |
| 152 | |
| 153 continue; | |
| 154 } | 147 } |
| 155 stream->OnStreamFrame(frames[i]); | 148 return; |
| 156 } | 149 } |
| 150 stream->OnStreamFrame(frame); |
| 157 } | 151 } |
| 158 | 152 |
| 159 void QuicSession::OnRstStream(const QuicRstStreamFrame& frame) { | 153 void QuicSession::OnRstStream(const QuicRstStreamFrame& frame) { |
| 160 if (ContainsKey(static_stream_map_, frame.stream_id)) { | 154 if (ContainsKey(static_stream_map_, frame.stream_id)) { |
| 161 connection()->SendConnectionCloseWithDetails( | 155 connection()->SendConnectionCloseWithDetails( |
| 162 QUIC_INVALID_STREAM_ID, "Attempt to reset a static stream"); | 156 QUIC_INVALID_STREAM_ID, "Attempt to reset a static stream"); |
| 163 return; | 157 return; |
| 164 } | 158 } |
| 165 | 159 |
| 166 ReliableQuicStream* stream = GetDynamicStream(frame.stream_id); | 160 ReliableQuicStream* stream = GetDynamicStream(frame.stream_id); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 195 LOG(DFATAL) << ENDPOINT | 189 LOG(DFATAL) << ENDPOINT |
| 196 << "Stream failed to close under OnConnectionClosed"; | 190 << "Stream failed to close under OnConnectionClosed"; |
| 197 CloseStream(id); | 191 CloseStream(id); |
| 198 } | 192 } |
| 199 } | 193 } |
| 200 } | 194 } |
| 201 | 195 |
| 202 void QuicSession::OnSuccessfulVersionNegotiation(const QuicVersion& version) { | 196 void QuicSession::OnSuccessfulVersionNegotiation(const QuicVersion& version) { |
| 203 } | 197 } |
| 204 | 198 |
| 205 void QuicSession::OnWindowUpdateFrames( | 199 void QuicSession::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) { |
| 206 const vector<QuicWindowUpdateFrame>& frames) { | 200 // Stream may be closed by the time we receive a WINDOW_UPDATE, so we can't |
| 207 bool connection_window_updated = false; | 201 // assume that it still exists. |
| 208 for (size_t i = 0; i < frames.size(); ++i) { | 202 QuicStreamId stream_id = frame.stream_id; |
| 209 // Stream may be closed by the time we receive a WINDOW_UPDATE, so we can't | 203 if (stream_id == kConnectionLevelId) { |
| 210 // assume that it still exists. | 204 // This is a window update that applies to the connection, rather than an |
| 211 QuicStreamId stream_id = frames[i].stream_id; | 205 // individual stream. |
| 212 if (stream_id == kConnectionLevelId) { | 206 DVLOG(1) << ENDPOINT << "Received connection level flow control window " |
| 213 // This is a window update that applies to the connection, rather than an | 207 "update with byte offset: " |
| 214 // individual stream. | 208 << frame.byte_offset; |
| 215 DVLOG(1) << ENDPOINT | 209 if (flow_controller_.UpdateSendWindowOffset(frame.byte_offset)) { |
| 216 << "Received connection level flow control window update with " | 210 // Connection level flow control window has increased, so blocked streams |
| 217 "byte offset: " << frames[i].byte_offset; | 211 // can write again. |
| 218 if (flow_controller_.UpdateSendWindowOffset(frames[i].byte_offset)) { | 212 // TODO(ianswett): I suspect this can be delayed until the packet |
| 219 connection_window_updated = true; | 213 // processing is complete. |
| 220 } | 214 OnCanWrite(); |
| 221 continue; | |
| 222 } | 215 } |
| 223 | 216 return; |
| 224 ReliableQuicStream* stream = GetStream(stream_id); | |
| 225 if (stream) { | |
| 226 stream->OnWindowUpdateFrame(frames[i]); | |
| 227 } | |
| 228 } | 217 } |
| 229 | 218 ReliableQuicStream* stream = GetStream(stream_id); |
| 230 // Connection level flow control window has increased, so blocked streams can | 219 if (stream) { |
| 231 // write again. | 220 stream->OnWindowUpdateFrame(frame); |
| 232 if (connection_window_updated) { | |
| 233 OnCanWrite(); | |
| 234 } | 221 } |
| 235 } | 222 } |
| 236 | 223 |
| 237 void QuicSession::OnBlockedFrames(const vector<QuicBlockedFrame>& frames) { | 224 void QuicSession::OnBlockedFrame(const QuicBlockedFrame& frame) { |
| 238 for (size_t i = 0; i < frames.size(); ++i) { | 225 // TODO(rjshade): Compare our flow control receive windows for specified |
| 239 // TODO(rjshade): Compare our flow control receive windows for specified | 226 // streams: if we have a large window then maybe something |
| 240 // streams: if we have a large window then maybe something | 227 // had gone wrong with the flow control accounting. |
| 241 // had gone wrong with the flow control accounting. | 228 DVLOG(1) << ENDPOINT |
| 242 DVLOG(1) << ENDPOINT << "Received BLOCKED frame with stream id: " | 229 << "Received BLOCKED frame with stream id: " << frame.stream_id; |
| 243 << frames[i].stream_id; | |
| 244 } | |
| 245 } | 230 } |
| 246 | 231 |
| 247 void QuicSession::OnCanWrite() { | 232 void QuicSession::OnCanWrite() { |
| 248 // We limit the number of writes to the number of pending streams. If more | 233 // We limit the number of writes to the number of pending streams. If more |
| 249 // streams become pending, WillingAndAbleToWrite will be true, which will | 234 // streams become pending, WillingAndAbleToWrite will be true, which will |
| 250 // cause the connection to request resumption before yielding to other | 235 // cause the connection to request resumption before yielding to other |
| 251 // connections. | 236 // connections. |
| 252 size_t num_writes = write_blocked_streams_.NumBlockedStreams(); | 237 size_t num_writes = write_blocked_streams_.NumBlockedStreams(); |
| 253 if (flow_controller_.IsBlocked()) { | 238 if (flow_controller_.IsBlocked()) { |
| 254 // If we are connection level flow control blocked, then only allow the | 239 // If we are connection level flow control blocked, then only allow the |
| (...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 708 } | 693 } |
| 709 for (auto const& kv : dynamic_stream_map_) { | 694 for (auto const& kv : dynamic_stream_map_) { |
| 710 if (kv.second->flow_controller()->IsBlocked()) { | 695 if (kv.second->flow_controller()->IsBlocked()) { |
| 711 return true; | 696 return true; |
| 712 } | 697 } |
| 713 } | 698 } |
| 714 return false; | 699 return false; |
| 715 } | 700 } |
| 716 | 701 |
| 717 } // namespace net | 702 } // namespace net |
| OLD | NEW |