OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "net/tools/quic/quic_client_base.h" |
| 6 |
| 7 #include "net/quic/crypto/quic_random.h" |
| 8 #include "net/quic/quic_server_id.h" |
| 9 |
| 10 namespace net { |
| 11 namespace tools { |
| 12 |
| 13 QuicClientBase::QuicClientBase(const QuicServerId& server_id, |
| 14 const QuicVersionVector& supported_versions, |
| 15 const QuicConfig& config) |
| 16 : server_id_(server_id), |
| 17 config_(config), |
| 18 supported_versions_(supported_versions), |
| 19 initial_max_packet_length_(0), |
| 20 num_stateless_rejects_received_(0), |
| 21 num_sent_client_hellos_(0), |
| 22 connection_error_(QUIC_NO_ERROR), |
| 23 connected_or_attempting_connect_(false) {} |
| 24 |
| 25 QuicClientBase::~QuicClientBase() {} |
| 26 |
| 27 bool QuicClientBase::Initialize() { |
| 28 num_sent_client_hellos_ = 0; |
| 29 num_stateless_rejects_received_ = 0; |
| 30 connection_error_ = QUIC_NO_ERROR; |
| 31 connected_or_attempting_connect_ = false; |
| 32 return true; |
| 33 } |
| 34 |
| 35 QuicClientBase::DummyPacketWriterFactory::DummyPacketWriterFactory( |
| 36 QuicPacketWriter* writer) |
| 37 : writer_(writer) {} |
| 38 |
| 39 QuicClientBase::DummyPacketWriterFactory::~DummyPacketWriterFactory() {} |
| 40 |
| 41 QuicPacketWriter* QuicClientBase::DummyPacketWriterFactory::Create( |
| 42 QuicConnection* /*connection*/) const { |
| 43 return writer_; |
| 44 } |
| 45 |
| 46 QuicClientSession* QuicClientBase::CreateQuicClientSession( |
| 47 QuicConnection* connection) { |
| 48 session_.reset( |
| 49 new QuicClientSession(config_, connection, server_id_, &crypto_config_)); |
| 50 if (initial_max_packet_length_ != 0) { |
| 51 session()->connection()->set_max_packet_length(initial_max_packet_length_); |
| 52 } |
| 53 return session_.get(); |
| 54 } |
| 55 |
| 56 bool QuicClientBase::EncryptionBeingEstablished() { |
| 57 return !session_->IsEncryptionEstablished() && |
| 58 session_->connection()->connected(); |
| 59 } |
| 60 |
| 61 QuicSpdyClientStream* QuicClientBase::CreateReliableClientStream() { |
| 62 if (!connected()) { |
| 63 return nullptr; |
| 64 } |
| 65 |
| 66 return session_->CreateOutgoingDynamicStream(); |
| 67 } |
| 68 |
| 69 void QuicClientBase::WaitForStreamToClose(QuicStreamId id) { |
| 70 DCHECK(connected()); |
| 71 |
| 72 while (connected() && !session_->IsClosedStream(id)) { |
| 73 WaitForEvents(); |
| 74 } |
| 75 } |
| 76 |
| 77 void QuicClientBase::WaitForCryptoHandshakeConfirmed() { |
| 78 DCHECK(connected()); |
| 79 |
| 80 while (connected() && !session_->IsCryptoHandshakeConfirmed()) { |
| 81 WaitForEvents(); |
| 82 } |
| 83 } |
| 84 |
| 85 bool QuicClientBase::connected() const { |
| 86 return session_.get() && session_->connection() && |
| 87 session_->connection()->connected(); |
| 88 } |
| 89 |
| 90 bool QuicClientBase::goaway_received() const { |
| 91 return session_ != nullptr && session_->goaway_received(); |
| 92 } |
| 93 |
| 94 int QuicClientBase::GetNumSentClientHellos() { |
| 95 // If we are not actively attempting to connect, the session object |
| 96 // corresponds to the previous connection and should not be used. |
| 97 const int current_session_hellos = !connected_or_attempting_connect_ |
| 98 ? 0 |
| 99 : session_->GetNumSentClientHellos(); |
| 100 return num_sent_client_hellos_ + current_session_hellos; |
| 101 } |
| 102 |
| 103 void QuicClientBase::UpdateStats() { |
| 104 num_sent_client_hellos_ += session()->GetNumSentClientHellos(); |
| 105 if (session()->error() == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) { |
| 106 ++num_stateless_rejects_received_; |
| 107 } |
| 108 } |
| 109 |
| 110 QuicErrorCode QuicClientBase::connection_error() const { |
| 111 // Return the high-level error if there was one. Otherwise, return the |
| 112 // connection error from the last session. |
| 113 if (connection_error_ != QUIC_NO_ERROR) { |
| 114 return connection_error_; |
| 115 } |
| 116 if (session_.get() == nullptr) { |
| 117 return QUIC_NO_ERROR; |
| 118 } |
| 119 return session_->error(); |
| 120 } |
| 121 |
| 122 QuicConnectionId QuicClientBase::GetNextConnectionId() { |
| 123 QuicConnectionId server_designated_id = GetNextServerDesignatedConnectionId(); |
| 124 return server_designated_id ? server_designated_id |
| 125 : GenerateNewConnectionId(); |
| 126 } |
| 127 |
| 128 QuicConnectionId QuicClientBase::GetNextServerDesignatedConnectionId() { |
| 129 QuicCryptoClientConfig::CachedState* cached = |
| 130 crypto_config_.LookupOrCreate(server_id_); |
| 131 // If the cached state indicates that we should use a server-designated |
| 132 // connection ID, then return that connection ID. |
| 133 CHECK(cached != nullptr) << "QuicClientCryptoConfig::LookupOrCreate returned " |
| 134 << "unexpected nullptr."; |
| 135 return cached->has_server_designated_connection_id() |
| 136 ? cached->GetNextServerDesignatedConnectionId() |
| 137 : 0; |
| 138 } |
| 139 |
| 140 QuicConnectionId QuicClientBase::GenerateNewConnectionId() { |
| 141 return QuicRandom::GetInstance()->RandUint64(); |
| 142 } |
| 143 |
| 144 } // namespace tools |
| 145 } // namespace net |
OLD | NEW |