Chromium Code Reviews| 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/spdy/spdy_session.h" | 5 #include "net/spdy/spdy_session.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <map> | 8 #include <map> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 583 TimeFunc time_func, | 583 TimeFunc time_func, |
| 584 const HostPortPair& trusted_spdy_proxy, | 584 const HostPortPair& trusted_spdy_proxy, |
| 585 NetLog* net_log) | 585 NetLog* net_log) |
| 586 : in_io_loop_(false), | 586 : in_io_loop_(false), |
| 587 spdy_session_key_(spdy_session_key), | 587 spdy_session_key_(spdy_session_key), |
| 588 pool_(NULL), | 588 pool_(NULL), |
| 589 http_server_properties_(http_server_properties), | 589 http_server_properties_(http_server_properties), |
| 590 transport_security_state_(transport_security_state), | 590 transport_security_state_(transport_security_state), |
| 591 read_buffer_(new IOBuffer(kReadBufferSize)), | 591 read_buffer_(new IOBuffer(kReadBufferSize)), |
| 592 stream_hi_water_mark_(kFirstStreamId), | 592 stream_hi_water_mark_(kFirstStreamId), |
| 593 last_accepted_push_stream_id_(0), | |
| 593 num_pushed_streams_(0u), | 594 num_pushed_streams_(0u), |
| 594 num_active_pushed_streams_(0u), | 595 num_active_pushed_streams_(0u), |
| 595 in_flight_write_frame_type_(DATA), | 596 in_flight_write_frame_type_(DATA), |
| 596 in_flight_write_frame_size_(0), | 597 in_flight_write_frame_size_(0), |
| 597 is_secure_(false), | 598 is_secure_(false), |
| 598 certificate_error_code_(OK), | 599 certificate_error_code_(OK), |
| 599 availability_state_(STATE_AVAILABLE), | 600 availability_state_(STATE_AVAILABLE), |
| 600 read_state_(READ_STATE_DO_READ), | 601 read_state_(READ_STATE_DO_READ), |
| 601 write_state_(WRITE_STATE_IDLE), | 602 write_state_(WRITE_STATE_IDLE), |
| 602 error_on_close_(OK), | 603 error_on_close_(OK), |
| (...skipping 1067 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1670 // and why. Don't GOAWAY on a graceful or idle close, as that may | 1671 // and why. Don't GOAWAY on a graceful or idle close, as that may |
| 1671 // unnecessarily wake the radio. We could technically GOAWAY on network errors | 1672 // unnecessarily wake the radio. We could technically GOAWAY on network errors |
| 1672 // (we'll probably fail to actually write it, but that's okay), however many | 1673 // (we'll probably fail to actually write it, but that's okay), however many |
| 1673 // unit-tests would need to be updated. | 1674 // unit-tests would need to be updated. |
| 1674 if (err != OK && | 1675 if (err != OK && |
| 1675 err != ERR_ABORTED && // Used by SpdySessionPool to close idle sessions. | 1676 err != ERR_ABORTED && // Used by SpdySessionPool to close idle sessions. |
| 1676 err != ERR_NETWORK_CHANGED && // Used to deprecate sessions on IP change. | 1677 err != ERR_NETWORK_CHANGED && // Used to deprecate sessions on IP change. |
| 1677 err != ERR_SOCKET_NOT_CONNECTED && | 1678 err != ERR_SOCKET_NOT_CONNECTED && |
| 1678 err != ERR_CONNECTION_CLOSED && err != ERR_CONNECTION_RESET) { | 1679 err != ERR_CONNECTION_CLOSED && err != ERR_CONNECTION_RESET) { |
| 1679 // Enqueue a GOAWAY to inform the peer of why we're closing the connection. | 1680 // Enqueue a GOAWAY to inform the peer of why we're closing the connection. |
| 1680 SpdyGoAwayIR goaway_ir(0, // Last accepted stream ID. | 1681 SpdyGoAwayIR goaway_ir(last_accepted_push_stream_id_, |
| 1681 MapNetErrorToGoAwayStatus(err), | 1682 MapNetErrorToGoAwayStatus(err), |
| 1682 description); | 1683 description); |
| 1683 EnqueueSessionWrite(HIGHEST, | 1684 EnqueueSessionWrite(HIGHEST, |
| 1684 GOAWAY, | 1685 GOAWAY, |
| 1685 scoped_ptr<SpdyFrame>( | 1686 scoped_ptr<SpdyFrame>( |
| 1686 buffered_spdy_framer_->SerializeFrame(goaway_ir))); | 1687 buffered_spdy_framer_->SerializeFrame(goaway_ir))); |
| 1687 } | 1688 } |
| 1688 | 1689 |
| 1689 availability_state_ = STATE_DRAINING; | 1690 availability_state_ = STATE_DRAINING; |
| 1690 error_on_close_ = err; | 1691 error_on_close_ = err; |
| (...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2353 DCHECK(active_streams_.find(stream_id) == active_streams_.end()); | 2354 DCHECK(active_streams_.find(stream_id) == active_streams_.end()); |
| 2354 } | 2355 } |
| 2355 } | 2356 } |
| 2356 } | 2357 } |
| 2357 | 2358 |
| 2358 bool SpdySession::OnUnknownFrame(SpdyStreamId stream_id, int frame_type) { | 2359 bool SpdySession::OnUnknownFrame(SpdyStreamId stream_id, int frame_type) { |
| 2359 // Validate stream id. | 2360 // Validate stream id. |
| 2360 // Was the frame sent on a stream id that has not been used in this session? | 2361 // Was the frame sent on a stream id that has not been used in this session? |
| 2361 if (stream_id % 2 == 1 && stream_id > stream_hi_water_mark_) | 2362 if (stream_id % 2 == 1 && stream_id > stream_hi_water_mark_) |
| 2362 return false; | 2363 return false; |
| 2363 // TODO(bnc): Track highest id for server initiated streams. | 2364 // TODO(bnc): Track highest id for server initiated streams. |
|
Johnny
2014/09/02 18:34:20
Optional bonus points: This TODO can be fixed now
baranovich
2014/09/02 19:02:19
Done.
| |
| 2364 return true; | 2365 return true; |
| 2365 } | 2366 } |
| 2366 | 2367 |
| 2367 void SpdySession::OnRstStream(SpdyStreamId stream_id, | 2368 void SpdySession::OnRstStream(SpdyStreamId stream_id, |
| 2368 SpdyRstStreamStatus status) { | 2369 SpdyRstStreamStatus status) { |
| 2369 CHECK(in_io_loop_); | 2370 CHECK(in_io_loop_); |
| 2370 | 2371 |
| 2371 std::string description; | 2372 std::string description; |
| 2372 net_log().AddEvent( | 2373 net_log().AddEvent( |
| 2373 NetLog::TYPE_SPDY_SESSION_RST_STREAM, | 2374 NetLog::TYPE_SPDY_SESSION_RST_STREAM, |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2514 } | 2515 } |
| 2515 } | 2516 } |
| 2516 | 2517 |
| 2517 bool SpdySession::TryCreatePushStream(SpdyStreamId stream_id, | 2518 bool SpdySession::TryCreatePushStream(SpdyStreamId stream_id, |
| 2518 SpdyStreamId associated_stream_id, | 2519 SpdyStreamId associated_stream_id, |
| 2519 SpdyPriority priority, | 2520 SpdyPriority priority, |
| 2520 const SpdyHeaderBlock& headers) { | 2521 const SpdyHeaderBlock& headers) { |
| 2521 // Server-initiated streams should have even sequence numbers. | 2522 // Server-initiated streams should have even sequence numbers. |
| 2522 if ((stream_id & 0x1) != 0) { | 2523 if ((stream_id & 0x1) != 0) { |
| 2523 LOG(WARNING) << "Received invalid push stream id " << stream_id; | 2524 LOG(WARNING) << "Received invalid push stream id " << stream_id; |
| 2525 if (GetProtocolVersion() > SPDY2) | |
| 2526 CloseSessionOnError(ERR_SPDY_PROTOCOL_ERROR, "Odd push stream id."); | |
| 2524 return false; | 2527 return false; |
| 2525 } | 2528 } |
| 2526 | 2529 |
| 2530 if (GetProtocolVersion() > SPDY2) { | |
| 2531 if (stream_id <= last_accepted_push_stream_id_) { | |
| 2532 LOG(WARNING) << "Received push stream id lesser or equal to the last " | |
| 2533 << "accepted before " << stream_id; | |
| 2534 CloseSessionOnError( | |
| 2535 ERR_SPDY_PROTOCOL_ERROR, | |
| 2536 "New push stream id must be greater than the last accepted."); | |
| 2537 return false; | |
| 2538 } | |
| 2539 } | |
| 2540 | |
| 2527 if (IsStreamActive(stream_id)) { | 2541 if (IsStreamActive(stream_id)) { |
| 2542 // For SPDY3 and higher we should not get here, we'll start going away | |
| 2543 // earlier on |last_seen_push_stream_id_| check. | |
| 2544 CHECK_GT(SPDY3, GetProtocolVersion()); | |
| 2528 LOG(WARNING) << "Received push for active stream " << stream_id; | 2545 LOG(WARNING) << "Received push for active stream " << stream_id; |
| 2529 return false; | 2546 return false; |
| 2530 } | 2547 } |
| 2531 | 2548 |
| 2549 last_accepted_push_stream_id_ = stream_id; | |
| 2550 | |
| 2532 RequestPriority request_priority = | 2551 RequestPriority request_priority = |
| 2533 ConvertSpdyPriorityToRequestPriority(priority, GetProtocolVersion()); | 2552 ConvertSpdyPriorityToRequestPriority(priority, GetProtocolVersion()); |
| 2534 | 2553 |
| 2535 if (availability_state_ == STATE_GOING_AWAY) { | 2554 if (availability_state_ == STATE_GOING_AWAY) { |
| 2536 // TODO(akalin): This behavior isn't in the SPDY spec, although it | 2555 // TODO(akalin): This behavior isn't in the SPDY spec, although it |
| 2537 // probably should be. | 2556 // probably should be. |
| 2538 EnqueueResetStreamFrame(stream_id, | 2557 EnqueueResetStreamFrame(stream_id, |
| 2539 request_priority, | 2558 request_priority, |
| 2540 RST_STREAM_REFUSED_STREAM, | 2559 RST_STREAM_REFUSED_STREAM, |
| 2541 "push stream request received when going away"); | 2560 "push stream request received when going away"); |
| (...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3207 if (!queue->empty()) { | 3226 if (!queue->empty()) { |
| 3208 SpdyStreamId stream_id = queue->front(); | 3227 SpdyStreamId stream_id = queue->front(); |
| 3209 queue->pop_front(); | 3228 queue->pop_front(); |
| 3210 return stream_id; | 3229 return stream_id; |
| 3211 } | 3230 } |
| 3212 } | 3231 } |
| 3213 return 0; | 3232 return 0; |
| 3214 } | 3233 } |
| 3215 | 3234 |
| 3216 } // namespace net | 3235 } // namespace net |
| OLD | NEW |