| 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/quic_connection.h" | 8 #include "net/quic/quic_connection.h" |
| 9 | 9 |
| 10 using base::StringPiece; | 10 using base::StringPiece; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 bool accepted = session_->OnPacket(self_address, peer_address, header, | 32 bool accepted = session_->OnPacket(self_address, peer_address, header, |
| 33 frame); | 33 frame); |
| 34 session_->PostProcessAfterData(); | 34 session_->PostProcessAfterData(); |
| 35 return accepted; | 35 return accepted; |
| 36 } | 36 } |
| 37 virtual void OnRstStream(const QuicRstStreamFrame& frame) OVERRIDE { | 37 virtual void OnRstStream(const QuicRstStreamFrame& frame) OVERRIDE { |
| 38 session_->OnRstStream(frame); | 38 session_->OnRstStream(frame); |
| 39 session_->PostProcessAfterData(); | 39 session_->PostProcessAfterData(); |
| 40 } | 40 } |
| 41 | 41 |
| 42 virtual void OnAck(AckedPackets acked_packets) OVERRIDE { | 42 virtual void OnGoAway(const QuicGoAwayFrame& frame) OVERRIDE { |
| 43 session_->OnGoAway(frame); |
| 44 session_->PostProcessAfterData(); |
| 45 } |
| 46 |
| 47 virtual void OnAck(const SequenceNumberSet& acked_packets) OVERRIDE { |
| 43 session_->OnAck(acked_packets); | 48 session_->OnAck(acked_packets); |
| 44 session_->PostProcessAfterData(); | 49 session_->PostProcessAfterData(); |
| 45 } | 50 } |
| 46 | 51 |
| 47 virtual bool OnCanWrite() OVERRIDE { | 52 virtual bool OnCanWrite() OVERRIDE { |
| 48 bool rc = session_->OnCanWrite(); | 53 bool rc = session_->OnCanWrite(); |
| 49 session_->PostProcessAfterData(); | 54 session_->PostProcessAfterData(); |
| 50 return rc; | 55 return rc; |
| 51 } | 56 } |
| 52 | 57 |
| 53 virtual void ConnectionClose(QuicErrorCode error, bool from_peer) OVERRIDE { | 58 virtual void ConnectionClose(QuicErrorCode error, bool from_peer) OVERRIDE { |
| 54 session_->ConnectionClose(error, from_peer); | 59 session_->ConnectionClose(error, from_peer); |
| 55 // The session will go away, so don't bother with cleanup. | 60 // The session will go away, so don't bother with cleanup. |
| 56 } | 61 } |
| 57 | 62 |
| 58 private: | 63 private: |
| 59 QuicSession* session_; | 64 QuicSession* session_; |
| 60 }; | 65 }; |
| 61 | 66 |
| 62 QuicSession::QuicSession(QuicConnection* connection, bool is_server) | 67 QuicSession::QuicSession(QuicConnection* connection, bool is_server) |
| 63 : connection_(connection), | 68 : connection_(connection), |
| 64 visitor_shim_(new VisitorShim(this)), | 69 visitor_shim_(new VisitorShim(this)), |
| 65 max_open_streams_(kDefaultMaxStreamsPerConnection), | 70 max_open_streams_(kDefaultMaxStreamsPerConnection), |
| 66 next_stream_id_(is_server ? 2 : 3), | 71 next_stream_id_(is_server ? 2 : 3), |
| 67 is_server_(is_server), | 72 is_server_(is_server), |
| 68 largest_peer_created_stream_id_(0) { | 73 largest_peer_created_stream_id_(0), |
| 74 goaway_received_(false), |
| 75 goaway_sent_(false) { |
| 69 connection->set_visitor(visitor_shim_.get()); | 76 connection->set_visitor(visitor_shim_.get()); |
| 70 } | 77 } |
| 71 | 78 |
| 72 QuicSession::~QuicSession() { | 79 QuicSession::~QuicSession() { |
| 73 STLDeleteElements(&closed_streams_); | 80 STLDeleteElements(&closed_streams_); |
| 74 STLDeleteValues(&stream_map_); | 81 STLDeleteValues(&stream_map_); |
| 75 } | 82 } |
| 76 | 83 |
| 77 bool QuicSession::OnPacket(const IPEndPoint& self_address, | 84 bool QuicSession::OnPacket(const IPEndPoint& self_address, |
| 78 const IPEndPoint& peer_address, | 85 const IPEndPoint& peer_address, |
| (...skipping 23 matching lines...) Expand all Loading... |
| 102 } | 109 } |
| 103 } | 110 } |
| 104 return true; | 111 return true; |
| 105 } | 112 } |
| 106 | 113 |
| 107 void QuicSession::OnRstStream(const QuicRstStreamFrame& frame) { | 114 void QuicSession::OnRstStream(const QuicRstStreamFrame& frame) { |
| 108 ReliableQuicStream* stream = GetStream(frame.stream_id); | 115 ReliableQuicStream* stream = GetStream(frame.stream_id); |
| 109 if (!stream) { | 116 if (!stream) { |
| 110 return; // Errors are handled by GetStream. | 117 return; // Errors are handled by GetStream. |
| 111 } | 118 } |
| 112 stream->OnStreamReset(frame.error_code, frame.offset); | 119 stream->OnStreamReset(frame.error_code); |
| 120 } |
| 121 |
| 122 void QuicSession::OnGoAway(const QuicGoAwayFrame& frame) { |
| 123 DCHECK(frame.last_good_stream_id < next_stream_id_); |
| 124 goaway_received_ = true; |
| 113 } | 125 } |
| 114 | 126 |
| 115 void QuicSession::ConnectionClose(QuicErrorCode error, bool from_peer) { | 127 void QuicSession::ConnectionClose(QuicErrorCode error, bool from_peer) { |
| 116 while (stream_map_.size() != 0) { | 128 while (stream_map_.size() != 0) { |
| 117 ReliableStreamMap::iterator it = stream_map_.begin(); | 129 ReliableStreamMap::iterator it = stream_map_.begin(); |
| 118 QuicStreamId id = it->first; | 130 QuicStreamId id = it->first; |
| 119 it->second->ConnectionClose(error, from_peer); | 131 it->second->ConnectionClose(error, from_peer); |
| 120 // The stream should call CloseStream as part of ConnectionClose. | 132 // The stream should call CloseStream as part of ConnectionClose. |
| 121 if (stream_map_.find(id) != stream_map_.end()) { | 133 if (stream_map_.find(id) != stream_map_.end()) { |
| 122 LOG(DFATAL) << "Stream failed to close under ConnectionClose"; | 134 LOG(DFATAL) << "Stream failed to close under ConnectionClose"; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 143 --remaining_writes; | 155 --remaining_writes; |
| 144 } | 156 } |
| 145 | 157 |
| 146 return write_blocked_streams_.empty(); | 158 return write_blocked_streams_.empty(); |
| 147 } | 159 } |
| 148 | 160 |
| 149 QuicConsumedData QuicSession::WriteData(QuicStreamId id, | 161 QuicConsumedData QuicSession::WriteData(QuicStreamId id, |
| 150 StringPiece data, | 162 StringPiece data, |
| 151 QuicStreamOffset offset, | 163 QuicStreamOffset offset, |
| 152 bool fin) { | 164 bool fin) { |
| 153 // TODO(wtc): type mismatch -- connection_->SendStreamData() returns a | |
| 154 // size_t. | |
| 155 return connection_->SendStreamData(id, data, offset, fin); | 165 return connection_->SendStreamData(id, data, offset, fin); |
| 156 } | 166 } |
| 157 | 167 |
| 158 void QuicSession::SendRstStream(QuicStreamId id, | 168 void QuicSession::SendRstStream(QuicStreamId id, |
| 159 QuicErrorCode error, | 169 QuicErrorCode error) { |
| 160 QuicStreamOffset offset) { | 170 connection_->SendRstStream(id, error); |
| 161 connection_->SendRstStream(id, error, offset); | |
| 162 CloseStream(id); | 171 CloseStream(id); |
| 163 } | 172 } |
| 164 | 173 |
| 174 void QuicSession::SendGoAway(QuicErrorCode error_code, const string& reason) { |
| 175 goaway_sent_ = true; |
| 176 connection_->SendGoAway(error_code, largest_peer_created_stream_id_, reason); |
| 177 } |
| 178 |
| 165 void QuicSession::CloseStream(QuicStreamId stream_id) { | 179 void QuicSession::CloseStream(QuicStreamId stream_id) { |
| 166 DLOG(INFO) << "Closing stream " << stream_id; | 180 DLOG(INFO) << "Closing stream " << stream_id; |
| 167 | 181 |
| 168 ReliableStreamMap::iterator it = stream_map_.find(stream_id); | 182 ReliableStreamMap::iterator it = stream_map_.find(stream_id); |
| 169 if (it == stream_map_.end()) { | 183 if (it == stream_map_.end()) { |
| 170 DLOG(INFO) << "Stream is already closed: " << stream_id; | 184 DLOG(INFO) << "Stream is already closed: " << stream_id; |
| 171 return; | 185 return; |
| 172 } | 186 } |
| 173 it->second->OnClose(); | 187 it->second->OnClose(); |
| 174 closed_streams_.push_back(it->second); | 188 closed_streams_.push_back(it->second); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 | 233 |
| 220 return GetIncomingReliableStream(stream_id); | 234 return GetIncomingReliableStream(stream_id); |
| 221 } | 235 } |
| 222 | 236 |
| 223 ReliableQuicStream* QuicSession::GetIncomingReliableStream( | 237 ReliableQuicStream* QuicSession::GetIncomingReliableStream( |
| 224 QuicStreamId stream_id) { | 238 QuicStreamId stream_id) { |
| 225 if (IsClosedStream(stream_id)) { | 239 if (IsClosedStream(stream_id)) { |
| 226 return NULL; | 240 return NULL; |
| 227 } | 241 } |
| 228 | 242 |
| 243 if (goaway_sent_) { |
| 244 // We've already sent a GoAway |
| 245 connection()->SendRstStream(stream_id, QUIC_PEER_GOING_AWAY); |
| 246 return NULL; |
| 247 } |
| 248 |
| 229 implicitly_created_streams_.erase(stream_id); | 249 implicitly_created_streams_.erase(stream_id); |
| 230 if (stream_id > largest_peer_created_stream_id_) { | 250 if (stream_id > largest_peer_created_stream_id_) { |
| 231 // TODO(rch) add unit test for this | 251 // TODO(rch) add unit test for this |
| 232 if (stream_id - largest_peer_created_stream_id_ > kMaxStreamIdDelta) { | 252 if (stream_id - largest_peer_created_stream_id_ > kMaxStreamIdDelta) { |
| 233 connection()->SendConnectionClose(QUIC_INVALID_STREAM_ID); | 253 connection()->SendConnectionClose(QUIC_INVALID_STREAM_ID); |
| 234 return NULL; | 254 return NULL; |
| 235 } | 255 } |
| 236 if (largest_peer_created_stream_id_ != 0) { | 256 if (largest_peer_created_stream_id_ != 0) { |
| 237 for (QuicStreamId id = largest_peer_created_stream_id_ + 2; | 257 for (QuicStreamId id = largest_peer_created_stream_id_ + 2; |
| 238 id < stream_id; | 258 id < stream_id; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 void QuicSession::MarkWriteBlocked(QuicStreamId id) { | 297 void QuicSession::MarkWriteBlocked(QuicStreamId id) { |
| 278 write_blocked_streams_.push_back(id); | 298 write_blocked_streams_.push_back(id); |
| 279 } | 299 } |
| 280 | 300 |
| 281 void QuicSession::PostProcessAfterData() { | 301 void QuicSession::PostProcessAfterData() { |
| 282 STLDeleteElements(&closed_streams_); | 302 STLDeleteElements(&closed_streams_); |
| 283 closed_streams_.clear(); | 303 closed_streams_.clear(); |
| 284 } | 304 } |
| 285 | 305 |
| 286 } // namespace net | 306 } // namespace net |
| OLD | NEW |