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

Side by Side Diff: net/quic/quic_session.cc

Issue 23691073: Land Recent QUIC changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Compiler/unittests fix Created 7 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 | Annotate | Revision Log
« no previous file with comments | « net/quic/quic_session.h ('k') | net/quic/quic_session_test.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/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 15 matching lines...) Expand all
26 // To avoid deleting a stream in mid-operation, we have a simple shim between 26 // To avoid deleting a stream in mid-operation, we have a simple shim between
27 // us and the stream, so we can delete any streams when we return from 27 // us and the stream, so we can delete any streams when we return from
28 // processing. 28 // processing.
29 // 29 //
30 // We could just override the base methods, but this makes it easier to make 30 // We could just override the base methods, but this makes it easier to make
31 // sure we don't miss any. 31 // sure we don't miss any.
32 class VisitorShim : public QuicConnectionVisitorInterface { 32 class VisitorShim : public QuicConnectionVisitorInterface {
33 public: 33 public:
34 explicit VisitorShim(QuicSession* session) : session_(session) {} 34 explicit VisitorShim(QuicSession* session) : session_(session) {}
35 35
36 virtual bool OnPacket(const IPEndPoint& self_address, 36 virtual bool OnStreamFrames(const vector<QuicStreamFrame>& frames) OVERRIDE {
37 const IPEndPoint& peer_address, 37 bool accepted = session_->OnStreamFrames(frames);
38 const QuicPacketHeader& header,
39 const vector<QuicStreamFrame>& frame) OVERRIDE {
40 bool accepted = session_->OnPacket(self_address, peer_address, header,
41 frame);
42 session_->PostProcessAfterData(); 38 session_->PostProcessAfterData();
43 return accepted; 39 return accepted;
44 } 40 }
45 virtual void OnRstStream(const QuicRstStreamFrame& frame) OVERRIDE { 41 virtual void OnRstStream(const QuicRstStreamFrame& frame) OVERRIDE {
46 session_->OnRstStream(frame); 42 session_->OnRstStream(frame);
47 session_->PostProcessAfterData(); 43 session_->PostProcessAfterData();
48 } 44 }
49 45
50 virtual void OnGoAway(const QuicGoAwayFrame& frame) OVERRIDE { 46 virtual void OnGoAway(const QuicGoAwayFrame& frame) OVERRIDE {
51 session_->OnGoAway(frame); 47 session_->OnGoAway(frame);
52 session_->PostProcessAfterData(); 48 session_->PostProcessAfterData();
53 } 49 }
54 50
55 virtual void OnAck(const SequenceNumberSet& acked_packets) OVERRIDE {
56 session_->OnAck(acked_packets);
57 session_->PostProcessAfterData();
58 }
59
60 virtual bool OnCanWrite() OVERRIDE { 51 virtual bool OnCanWrite() OVERRIDE {
61 bool rc = session_->OnCanWrite(); 52 bool rc = session_->OnCanWrite();
62 session_->PostProcessAfterData(); 53 session_->PostProcessAfterData();
63 return rc; 54 return rc;
64 } 55 }
65 56
66 virtual void OnSuccessfulVersionNegotiation( 57 virtual void OnSuccessfulVersionNegotiation(
67 const QuicVersion& version) OVERRIDE { 58 const QuicVersion& version) OVERRIDE {
68 session_->OnSuccessfulVersionNegotiation(version); 59 session_->OnSuccessfulVersionNegotiation(version);
69 } 60 }
70 61
71 virtual void ConnectionClose(QuicErrorCode error, bool from_peer) OVERRIDE { 62 virtual void ConnectionClose(QuicErrorCode error, bool from_peer) OVERRIDE {
72 session_->ConnectionClose(error, from_peer); 63 session_->ConnectionClose(error, from_peer);
73 // The session will go away, so don't bother with cleanup. 64 // The session will go away, so don't bother with cleanup.
74 } 65 }
75 66
67 virtual bool HasPendingHandshake() const OVERRIDE {
68 return session_->HasPendingHandshake();
69 }
70
76 private: 71 private:
77 QuicSession* session_; 72 QuicSession* session_;
78 }; 73 };
79 74
80 QuicSession::QuicSession(QuicConnection* connection, 75 QuicSession::QuicSession(QuicConnection* connection,
81 const QuicConfig& config, 76 const QuicConfig& config,
82 bool is_server) 77 bool is_server)
83 : connection_(connection), 78 : connection_(connection),
84 visitor_shim_(new VisitorShim(this)), 79 visitor_shim_(new VisitorShim(this)),
85 config_(config), 80 config_(config),
86 max_open_streams_(config_.max_streams_per_connection()), 81 max_open_streams_(config_.max_streams_per_connection()),
87 next_stream_id_(is_server ? 2 : 3), 82 next_stream_id_(is_server ? 2 : 3),
88 is_server_(is_server), 83 is_server_(is_server),
89 largest_peer_created_stream_id_(0), 84 largest_peer_created_stream_id_(0),
90 error_(QUIC_NO_ERROR), 85 error_(QUIC_NO_ERROR),
91 goaway_received_(false), 86 goaway_received_(false),
92 goaway_sent_(false) { 87 goaway_sent_(false),
88 has_pending_handshake_(false) {
93 89
94 connection_->set_visitor(visitor_shim_.get()); 90 connection_->set_visitor(visitor_shim_.get());
95 connection_->SetIdleNetworkTimeout(config_.idle_connection_state_lifetime()); 91 connection_->SetIdleNetworkTimeout(config_.idle_connection_state_lifetime());
96 if (connection_->connected()) { 92 if (connection_->connected()) {
97 connection_->SetOverallConnectionTimeout( 93 connection_->SetOverallConnectionTimeout(
98 config_.max_time_before_crypto_handshake()); 94 config_.max_time_before_crypto_handshake());
99 } 95 }
100 // TODO(satyamshekhar): Set congestion control and ICSL also. 96 // TODO(satyamshekhar): Set congestion control and ICSL also.
101 } 97 }
102 98
103 QuicSession::~QuicSession() { 99 QuicSession::~QuicSession() {
104 STLDeleteElements(&closed_streams_); 100 STLDeleteElements(&closed_streams_);
105 STLDeleteValues(&stream_map_); 101 STLDeleteValues(&stream_map_);
106 } 102 }
107 103
108 bool QuicSession::OnPacket(const IPEndPoint& self_address, 104 bool QuicSession::OnStreamFrames(const vector<QuicStreamFrame>& frames) {
109 const IPEndPoint& peer_address,
110 const QuicPacketHeader& header,
111 const vector<QuicStreamFrame>& frames) {
112 if (header.public_header.guid != connection()->guid()) {
113 DLOG(INFO) << ENDPOINT << "Got packet header for invalid GUID: "
114 << header.public_header.guid;
115 return false;
116 }
117
118 for (size_t i = 0; i < frames.size(); ++i) { 105 for (size_t i = 0; i < frames.size(); ++i) {
119 // TODO(rch) deal with the error case of stream id 0 106 // TODO(rch) deal with the error case of stream id 0
120 if (IsClosedStream(frames[i].stream_id)) { 107 if (IsClosedStream(frames[i].stream_id)) {
121 // If we get additional frames for a stream where we didn't process 108 // If we get additional frames for a stream where we didn't process
122 // headers, it's highly likely our compression context will end up 109 // headers, it's highly likely our compression context will end up
123 // permanently out of sync with the peer's, so we give up and close the 110 // permanently out of sync with the peer's, so we give up and close the
124 // connection. 111 // connection.
125 if (ContainsKey(prematurely_closed_streams_, frames[i].stream_id)) { 112 if (ContainsKey(prematurely_closed_streams_, frames[i].stream_id)) {
126 connection()->SendConnectionClose( 113 connection()->SendConnectionClose(
127 QUIC_STREAM_RST_BEFORE_HEADERS_DECOMPRESSED); 114 QUIC_STREAM_RST_BEFORE_HEADERS_DECOMPRESSED);
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 } 202 }
216 203
217 bool QuicSession::OnCanWrite() { 204 bool QuicSession::OnCanWrite() {
218 // We latch this here rather than doing a traditional loop, because streams 205 // We latch this here rather than doing a traditional loop, because streams
219 // may be modifying the list as we loop. 206 // may be modifying the list as we loop.
220 int remaining_writes = write_blocked_streams_.NumBlockedStreams(); 207 int remaining_writes = write_blocked_streams_.NumBlockedStreams();
221 208
222 while (!connection_->HasQueuedData() && 209 while (!connection_->HasQueuedData() &&
223 remaining_writes > 0) { 210 remaining_writes > 0) {
224 DCHECK(write_blocked_streams_.HasWriteBlockedStreams()); 211 DCHECK(write_blocked_streams_.HasWriteBlockedStreams());
225 ReliableQuicStream* stream = NULL;
226 int index = write_blocked_streams_.GetHighestPriorityWriteBlockedList(); 212 int index = write_blocked_streams_.GetHighestPriorityWriteBlockedList();
227 if (index != -1) { 213 if (index == -1) {
228 stream = GetStream(write_blocked_streams_.PopFront(index)); 214 LOG(DFATAL) << "WriteBlockedStream is missing";
215 connection_->CloseConnection(QUIC_INTERNAL_ERROR, false);
216 return true; // We have no write blocked streams.
229 } 217 }
218 QuicStreamId stream_id = write_blocked_streams_.PopFront(index);
219 if (stream_id == kCryptoStreamId) {
220 has_pending_handshake_ = false; // We just popped it.
221 }
222 ReliableQuicStream* stream = GetStream(stream_id);
230 if (stream != NULL) { 223 if (stream != NULL) {
231 // If the stream can't write all bytes, it'll re-add itself to the blocked 224 // If the stream can't write all bytes, it'll re-add itself to the blocked
232 // list. 225 // list.
233 stream->OnCanWrite(); 226 stream->OnCanWrite();
234 } 227 }
235 --remaining_writes; 228 --remaining_writes;
236 } 229 }
237 230
238 return !write_blocked_streams_.HasWriteBlockedStreams(); 231 return !write_blocked_streams_.HasWriteBlockedStreams();
239 } 232 }
240 233
234 bool QuicSession::HasPendingHandshake() const {
235 return has_pending_handshake_;
236 }
237
241 QuicConsumedData QuicSession::WritevData(QuicStreamId id, 238 QuicConsumedData QuicSession::WritevData(QuicStreamId id,
242 const struct iovec* iov, 239 const struct iovec* iov,
243 int count, 240 int iov_count,
244 QuicStreamOffset offset, 241 QuicStreamOffset offset,
245 bool fin) { 242 bool fin) {
246 return connection_->SendvStreamData(id, iov, count, offset, fin); 243 return connection_->SendvStreamData(id, iov, iov_count, offset, fin);
247 } 244 }
248 245
249 void QuicSession::SendRstStream(QuicStreamId id, 246 void QuicSession::SendRstStream(QuicStreamId id,
250 QuicRstStreamErrorCode error) { 247 QuicRstStreamErrorCode error) {
251 connection_->SendRstStream(id, error); 248 connection_->SendRstStream(id, error);
252 CloseStreamInner(id, true); 249 CloseStreamInner(id, true);
253 } 250 }
254 251
255 void QuicSession::SendGoAway(QuicErrorCode error_code, const string& reason) { 252 void QuicSession::SendGoAway(QuicErrorCode error_code, const string& reason) {
256 goaway_sent_ = true; 253 goaway_sent_ = true;
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 const CryptoHandshakeMessage& message) { 371 const CryptoHandshakeMessage& message) {
375 } 372 }
376 373
377 QuicConfig* QuicSession::config() { 374 QuicConfig* QuicSession::config() {
378 return &config_; 375 return &config_;
379 } 376 }
380 377
381 void QuicSession::ActivateStream(ReliableQuicStream* stream) { 378 void QuicSession::ActivateStream(ReliableQuicStream* stream) {
382 DLOG(INFO) << ENDPOINT << "num_streams: " << stream_map_.size() 379 DLOG(INFO) << ENDPOINT << "num_streams: " << stream_map_.size()
383 << ". activating " << stream->id(); 380 << ". activating " << stream->id();
384 DCHECK(stream_map_.count(stream->id()) == 0); 381 DCHECK_EQ(stream_map_.count(stream->id()), 0u);
385 stream_map_[stream->id()] = stream; 382 stream_map_[stream->id()] = stream;
386 } 383 }
387 384
388 QuicStreamId QuicSession::GetNextStreamId() { 385 QuicStreamId QuicSession::GetNextStreamId() {
389 QuicStreamId id = next_stream_id_; 386 QuicStreamId id = next_stream_id_;
390 next_stream_id_ += 2; 387 next_stream_id_ += 2;
391 return id; 388 return id;
392 } 389 }
393 390
394 ReliableQuicStream* QuicSession::GetStream(const QuicStreamId stream_id) { 391 ReliableQuicStream* QuicSession::GetStream(const QuicStreamId stream_id) {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 return id <= largest_peer_created_stream_id_ && 471 return id <= largest_peer_created_stream_id_ &&
475 implicitly_created_streams_.count(id) == 0; 472 implicitly_created_streams_.count(id) == 0;
476 } 473 }
477 474
478 size_t QuicSession::GetNumOpenStreams() const { 475 size_t QuicSession::GetNumOpenStreams() const {
479 return stream_map_.size() + implicitly_created_streams_.size() - 476 return stream_map_.size() + implicitly_created_streams_.size() -
480 zombie_streams_.size(); 477 zombie_streams_.size();
481 } 478 }
482 479
483 void QuicSession::MarkWriteBlocked(QuicStreamId id, QuicPriority priority) { 480 void QuicSession::MarkWriteBlocked(QuicStreamId id, QuicPriority priority) {
481 if (id == kCryptoStreamId) {
482 DCHECK(!has_pending_handshake_);
483 has_pending_handshake_ = true;
484 // TODO(jar): Be sure to use the highest priority for the crypto stream,
485 // perhaps by adding a "special" priority for it that is higher than
486 // kHighestPriority.
487 priority = kHighestPriority;
488 }
484 write_blocked_streams_.PushBack(id, priority); 489 write_blocked_streams_.PushBack(id, priority);
485 } 490 }
486 491
487 void QuicSession::MarkDecompressionBlocked(QuicHeaderId header_id, 492 void QuicSession::MarkDecompressionBlocked(QuicHeaderId header_id,
488 QuicStreamId stream_id) { 493 QuicStreamId stream_id) {
489 decompression_blocked_streams_[header_id] = stream_id; 494 decompression_blocked_streams_[header_id] = stream_id;
490 } 495 }
491 496
492 bool QuicSession::GetSSLInfo(SSLInfo* ssl_info) { 497 bool QuicSession::GetSSLInfo(SSLInfo* ssl_info) {
493 NOTIMPLEMENTED(); 498 NOTIMPLEMENTED();
494 return false; 499 return false;
495 } 500 }
496 501
497 void QuicSession::PostProcessAfterData() { 502 void QuicSession::PostProcessAfterData() {
498 STLDeleteElements(&closed_streams_); 503 STLDeleteElements(&closed_streams_);
499 closed_streams_.clear(); 504 closed_streams_.clear();
500 } 505 }
501 506
502 } // namespace net 507 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_session.h ('k') | net/quic/quic_session_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698