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.
5 #include "net/tools/quic/quic_client_base.h"
7 #include "net/quic/crypto/quic_random.h"
8 #include "net/quic/quic_server_id.h"
13 QuicClientBase::QuicClientBase(const QuicServerId
& server_id
,
14 const QuicVersionVector
& supported_versions
,
15 const QuicConfig
& config
)
16 : server_id_(server_id
),
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) {}
25 QuicClientBase::~QuicClientBase() {}
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;
35 QuicClientBase::DummyPacketWriterFactory::DummyPacketWriterFactory(
36 QuicPacketWriter
* writer
)
39 QuicClientBase::DummyPacketWriterFactory::~DummyPacketWriterFactory() {}
41 QuicPacketWriter
* QuicClientBase::DummyPacketWriterFactory::Create(
42 QuicConnection
* /*connection*/) const {
46 QuicClientSession
* QuicClientBase::CreateQuicClientSession(
47 QuicConnection
* connection
) {
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_
);
53 return session_
.get();
56 bool QuicClientBase::EncryptionBeingEstablished() {
57 return !session_
->IsEncryptionEstablished() &&
58 session_
->connection()->connected();
61 QuicSpdyClientStream
* QuicClientBase::CreateReliableClientStream() {
66 return session_
->CreateOutgoingDynamicStream();
69 void QuicClientBase::WaitForStreamToClose(QuicStreamId id
) {
72 while (connected() && !session_
->IsClosedStream(id
)) {
77 void QuicClientBase::WaitForCryptoHandshakeConfirmed() {
80 while (connected() && !session_
->IsCryptoHandshakeConfirmed()) {
85 bool QuicClientBase::connected() const {
86 return session_
.get() && session_
->connection() &&
87 session_
->connection()->connected();
90 bool QuicClientBase::goaway_received() const {
91 return session_
!= nullptr && session_
->goaway_received();
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_
99 : session_
->GetNumSentClientHellos();
100 return num_sent_client_hellos_
+ current_session_hellos
;
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_
;
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_
;
116 if (session_
.get() == nullptr) {
117 return QUIC_NO_ERROR
;
119 return session_
->error();
122 QuicConnectionId
QuicClientBase::GetNextConnectionId() {
123 QuicConnectionId server_designated_id
= GetNextServerDesignatedConnectionId();
124 return server_designated_id
? server_designated_id
125 : GenerateNewConnectionId();
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()
140 QuicConnectionId
QuicClientBase::GenerateNewConnectionId() {
141 return QuicRandom::GetInstance()->RandUint64();