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/ssl/ssl_info.h" | 10 #include "net/ssl/ssl_info.h" |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 if (ContainsKey(zombie_streams_, stream->id())) { | 172 if (ContainsKey(zombie_streams_, stream->id())) { |
173 // If this was a zombie stream then we close it out now. | 173 // If this was a zombie stream then we close it out now. |
174 CloseZombieStream(stream->id()); | 174 CloseZombieStream(stream->id()); |
175 // However, since the headers still have not been decompressed, we want to | 175 // However, since the headers still have not been decompressed, we want to |
176 // mark it a prematurely closed so that if we ever receive frames | 176 // mark it a prematurely closed so that if we ever receive frames |
177 // for this stream we can close the connection. | 177 // for this stream we can close the connection. |
178 DCHECK(!stream->headers_decompressed()); | 178 DCHECK(!stream->headers_decompressed()); |
179 AddPrematurelyClosedStream(frame.stream_id); | 179 AddPrematurelyClosedStream(frame.stream_id); |
180 return; | 180 return; |
181 } | 181 } |
| 182 if (stream->stream_bytes_read() > 0 && !stream->headers_decompressed()) { |
| 183 connection()->SendConnectionClose( |
| 184 QUIC_STREAM_RST_BEFORE_HEADERS_DECOMPRESSED); |
| 185 } |
182 stream->OnStreamReset(frame.error_code); | 186 stream->OnStreamReset(frame.error_code); |
183 } | 187 } |
184 | 188 |
185 void QuicSession::OnGoAway(const QuicGoAwayFrame& frame) { | 189 void QuicSession::OnGoAway(const QuicGoAwayFrame& frame) { |
186 DCHECK(frame.last_good_stream_id < next_stream_id_); | 190 DCHECK(frame.last_good_stream_id < next_stream_id_); |
187 goaway_received_ = true; | 191 goaway_received_ = true; |
188 } | 192 } |
189 | 193 |
190 void QuicSession::OnConnectionClosed(QuicErrorCode error, bool from_peer) { | 194 void QuicSession::OnConnectionClosed(QuicErrorCode error, bool from_peer) { |
191 DCHECK(!connection_->connected()); | 195 DCHECK(!connection_->connected()); |
(...skipping 15 matching lines...) Expand all Loading... |
207 } | 211 } |
208 | 212 |
209 bool QuicSession::OnCanWrite() { | 213 bool QuicSession::OnCanWrite() { |
210 // We latch this here rather than doing a traditional loop, because streams | 214 // We latch this here rather than doing a traditional loop, because streams |
211 // may be modifying the list as we loop. | 215 // may be modifying the list as we loop. |
212 int remaining_writes = write_blocked_streams_.NumBlockedStreams(); | 216 int remaining_writes = write_blocked_streams_.NumBlockedStreams(); |
213 | 217 |
214 while (!connection_->HasQueuedData() && | 218 while (!connection_->HasQueuedData() && |
215 remaining_writes > 0) { | 219 remaining_writes > 0) { |
216 DCHECK(write_blocked_streams_.HasWriteBlockedStreams()); | 220 DCHECK(write_blocked_streams_.HasWriteBlockedStreams()); |
217 int index = write_blocked_streams_.GetHighestPriorityWriteBlockedList(); | 221 if (!write_blocked_streams_.HasWriteBlockedStreams()) { |
218 if (index == -1) { | |
219 LOG(DFATAL) << "WriteBlockedStream is missing"; | 222 LOG(DFATAL) << "WriteBlockedStream is missing"; |
220 connection_->CloseConnection(QUIC_INTERNAL_ERROR, false); | 223 connection_->CloseConnection(QUIC_INTERNAL_ERROR, false); |
221 return true; // We have no write blocked streams. | 224 return true; // We have no write blocked streams. |
222 } | 225 } |
| 226 int index = write_blocked_streams_.GetHighestPriorityWriteBlockedList(); |
223 QuicStreamId stream_id = write_blocked_streams_.PopFront(index); | 227 QuicStreamId stream_id = write_blocked_streams_.PopFront(index); |
224 if (stream_id == kCryptoStreamId) { | 228 if (stream_id == kCryptoStreamId) { |
225 has_pending_handshake_ = false; // We just popped it. | 229 has_pending_handshake_ = false; // We just popped it. |
226 } | 230 } |
227 ReliableQuicStream* stream = GetStream(stream_id); | 231 ReliableQuicStream* stream = GetStream(stream_id); |
228 if (stream != NULL) { | 232 if (stream != NULL) { |
229 // If the stream can't write all bytes, it'll re-add itself to the blocked | 233 // If the stream can't write all bytes, it'll re-add itself to the blocked |
230 // list. | 234 // list. |
231 stream->OnCanWrite(); | 235 stream->OnCanWrite(); |
232 } | 236 } |
233 --remaining_writes; | 237 --remaining_writes; |
234 } | 238 } |
235 | 239 |
236 return !write_blocked_streams_.HasWriteBlockedStreams(); | 240 return !write_blocked_streams_.HasWriteBlockedStreams(); |
237 } | 241 } |
238 | 242 |
239 bool QuicSession::HasPendingHandshake() const { | 243 bool QuicSession::HasPendingHandshake() const { |
240 return has_pending_handshake_; | 244 return has_pending_handshake_; |
241 } | 245 } |
242 | 246 |
243 QuicConsumedData QuicSession::WritevData(QuicStreamId id, | 247 QuicConsumedData QuicSession::WritevData( |
244 const struct iovec* iov, | 248 QuicStreamId id, |
245 int iov_count, | 249 const struct iovec* iov, |
246 QuicStreamOffset offset, | 250 int iov_count, |
247 bool fin) { | 251 QuicStreamOffset offset, |
| 252 bool fin, |
| 253 QuicAckNotifier::DelegateInterface* ack_notifier_delegate) { |
248 IOVector data; | 254 IOVector data; |
249 data.AppendIovec(iov, iov_count); | 255 data.AppendIovec(iov, iov_count); |
250 return connection_->SendStreamData(id, data, offset, fin, NULL); | 256 return connection_->SendStreamData(id, data, offset, fin, |
| 257 ack_notifier_delegate); |
251 } | 258 } |
252 | 259 |
253 void QuicSession::SendRstStream(QuicStreamId id, | 260 void QuicSession::SendRstStream(QuicStreamId id, |
254 QuicRstStreamErrorCode error) { | 261 QuicRstStreamErrorCode error) { |
255 connection_->SendRstStream(id, error); | 262 connection_->SendRstStream(id, error); |
256 CloseStreamInner(id, true); | 263 CloseStreamInner(id, true); |
257 } | 264 } |
258 | 265 |
259 void QuicSession::SendGoAway(QuicErrorCode error_code, const string& reason) { | 266 void QuicSession::SendGoAway(QuicErrorCode error_code, const string& reason) { |
260 goaway_sent_ = true; | 267 goaway_sent_ = true; |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
507 NOTIMPLEMENTED(); | 514 NOTIMPLEMENTED(); |
508 return false; | 515 return false; |
509 } | 516 } |
510 | 517 |
511 void QuicSession::PostProcessAfterData() { | 518 void QuicSession::PostProcessAfterData() { |
512 STLDeleteElements(&closed_streams_); | 519 STLDeleteElements(&closed_streams_); |
513 closed_streams_.clear(); | 520 closed_streams_.clear(); |
514 } | 521 } |
515 | 522 |
516 } // namespace net | 523 } // namespace net |
OLD | NEW |