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

Side by Side Diff: net/spdy/spdy_session.cc

Issue 511283005: Go away on odd push and already seen push stream ids (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add push stream handling to OnUnknownFrame Created 6 years, 3 months 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/spdy/spdy_session.h ('k') | net/spdy/spdy_session_unittest.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/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
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
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
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
2365 if (stream_id % 2 == 0 && stream_id > last_accepted_push_stream_id_)
2366 return false;
2367
2364 return true; 2368 return true;
2365 } 2369 }
2366 2370
2367 void SpdySession::OnRstStream(SpdyStreamId stream_id, 2371 void SpdySession::OnRstStream(SpdyStreamId stream_id,
2368 SpdyRstStreamStatus status) { 2372 SpdyRstStreamStatus status) {
2369 CHECK(in_io_loop_); 2373 CHECK(in_io_loop_);
2370 2374
2371 std::string description; 2375 std::string description;
2372 net_log().AddEvent( 2376 net_log().AddEvent(
2373 NetLog::TYPE_SPDY_SESSION_RST_STREAM, 2377 NetLog::TYPE_SPDY_SESSION_RST_STREAM,
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
2514 } 2518 }
2515 } 2519 }
2516 2520
2517 bool SpdySession::TryCreatePushStream(SpdyStreamId stream_id, 2521 bool SpdySession::TryCreatePushStream(SpdyStreamId stream_id,
2518 SpdyStreamId associated_stream_id, 2522 SpdyStreamId associated_stream_id,
2519 SpdyPriority priority, 2523 SpdyPriority priority,
2520 const SpdyHeaderBlock& headers) { 2524 const SpdyHeaderBlock& headers) {
2521 // Server-initiated streams should have even sequence numbers. 2525 // Server-initiated streams should have even sequence numbers.
2522 if ((stream_id & 0x1) != 0) { 2526 if ((stream_id & 0x1) != 0) {
2523 LOG(WARNING) << "Received invalid push stream id " << stream_id; 2527 LOG(WARNING) << "Received invalid push stream id " << stream_id;
2528 if (GetProtocolVersion() > SPDY2)
2529 CloseSessionOnError(ERR_SPDY_PROTOCOL_ERROR, "Odd push stream id.");
2524 return false; 2530 return false;
2525 } 2531 }
2526 2532
2533 if (GetProtocolVersion() > SPDY2) {
2534 if (stream_id <= last_accepted_push_stream_id_) {
2535 LOG(WARNING) << "Received push stream id lesser or equal to the last "
2536 << "accepted before " << stream_id;
2537 CloseSessionOnError(
2538 ERR_SPDY_PROTOCOL_ERROR,
2539 "New push stream id must be greater than the last accepted.");
2540 return false;
2541 }
2542 }
2543
2527 if (IsStreamActive(stream_id)) { 2544 if (IsStreamActive(stream_id)) {
2545 // For SPDY3 and higher we should not get here, we'll start going away
2546 // earlier on |last_seen_push_stream_id_| check.
2547 CHECK_GT(SPDY3, GetProtocolVersion());
2528 LOG(WARNING) << "Received push for active stream " << stream_id; 2548 LOG(WARNING) << "Received push for active stream " << stream_id;
2529 return false; 2549 return false;
2530 } 2550 }
2531 2551
2552 last_accepted_push_stream_id_ = stream_id;
2553
2532 RequestPriority request_priority = 2554 RequestPriority request_priority =
2533 ConvertSpdyPriorityToRequestPriority(priority, GetProtocolVersion()); 2555 ConvertSpdyPriorityToRequestPriority(priority, GetProtocolVersion());
2534 2556
2535 if (availability_state_ == STATE_GOING_AWAY) { 2557 if (availability_state_ == STATE_GOING_AWAY) {
2536 // TODO(akalin): This behavior isn't in the SPDY spec, although it 2558 // TODO(akalin): This behavior isn't in the SPDY spec, although it
2537 // probably should be. 2559 // probably should be.
2538 EnqueueResetStreamFrame(stream_id, 2560 EnqueueResetStreamFrame(stream_id,
2539 request_priority, 2561 request_priority,
2540 RST_STREAM_REFUSED_STREAM, 2562 RST_STREAM_REFUSED_STREAM,
2541 "push stream request received when going away"); 2563 "push stream request received when going away");
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after
3207 if (!queue->empty()) { 3229 if (!queue->empty()) {
3208 SpdyStreamId stream_id = queue->front(); 3230 SpdyStreamId stream_id = queue->front();
3209 queue->pop_front(); 3231 queue->pop_front();
3210 return stream_id; 3232 return stream_id;
3211 } 3233 }
3212 } 3234 }
3213 return 0; 3235 return 0;
3214 } 3236 }
3215 3237
3216 } // namespace net 3238 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_session.h ('k') | net/spdy/spdy_session_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698