Index: net/tools/quic/quic_client_base.cc |
diff --git a/net/tools/quic/quic_client_base.cc b/net/tools/quic/quic_client_base.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..33f0ef122dded37900ff6bceb2b57d776691b74f |
--- /dev/null |
+++ b/net/tools/quic/quic_client_base.cc |
@@ -0,0 +1,145 @@ |
+// Copyright (c) 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "net/tools/quic/quic_client_base.h" |
+ |
+#include "net/quic/crypto/quic_random.h" |
+#include "net/quic/quic_server_id.h" |
+ |
+namespace net { |
+namespace tools { |
+ |
+QuicClientBase::QuicClientBase(const QuicServerId& server_id, |
+ const QuicVersionVector& supported_versions, |
+ const QuicConfig& config) |
+ : server_id_(server_id), |
+ config_(config), |
+ supported_versions_(supported_versions), |
+ initial_max_packet_length_(0), |
+ num_stateless_rejects_received_(0), |
+ num_sent_client_hellos_(0), |
+ connection_error_(QUIC_NO_ERROR), |
+ connected_or_attempting_connect_(false) {} |
+ |
+QuicClientBase::~QuicClientBase() {} |
+ |
+bool QuicClientBase::Initialize() { |
+ num_sent_client_hellos_ = 0; |
+ num_stateless_rejects_received_ = 0; |
+ connection_error_ = QUIC_NO_ERROR; |
+ connected_or_attempting_connect_ = false; |
+ return true; |
+} |
+ |
+QuicClientBase::DummyPacketWriterFactory::DummyPacketWriterFactory( |
+ QuicPacketWriter* writer) |
+ : writer_(writer) {} |
+ |
+QuicClientBase::DummyPacketWriterFactory::~DummyPacketWriterFactory() {} |
+ |
+QuicPacketWriter* QuicClientBase::DummyPacketWriterFactory::Create( |
+ QuicConnection* /*connection*/) const { |
+ return writer_; |
+} |
+ |
+QuicClientSession* QuicClientBase::CreateQuicClientSession( |
+ QuicConnection* connection) { |
+ session_.reset( |
+ new QuicClientSession(config_, connection, server_id_, &crypto_config_)); |
+ if (initial_max_packet_length_ != 0) { |
+ session()->connection()->set_max_packet_length(initial_max_packet_length_); |
+ } |
+ return session_.get(); |
+} |
+ |
+bool QuicClientBase::EncryptionBeingEstablished() { |
+ return !session_->IsEncryptionEstablished() && |
+ session_->connection()->connected(); |
+} |
+ |
+QuicSpdyClientStream* QuicClientBase::CreateReliableClientStream() { |
+ if (!connected()) { |
+ return nullptr; |
+ } |
+ |
+ return session_->CreateOutgoingDynamicStream(); |
+} |
+ |
+void QuicClientBase::WaitForStreamToClose(QuicStreamId id) { |
+ DCHECK(connected()); |
+ |
+ while (connected() && !session_->IsClosedStream(id)) { |
+ WaitForEvents(); |
+ } |
+} |
+ |
+void QuicClientBase::WaitForCryptoHandshakeConfirmed() { |
+ DCHECK(connected()); |
+ |
+ while (connected() && !session_->IsCryptoHandshakeConfirmed()) { |
+ WaitForEvents(); |
+ } |
+} |
+ |
+bool QuicClientBase::connected() const { |
+ return session_.get() && session_->connection() && |
+ session_->connection()->connected(); |
+} |
+ |
+bool QuicClientBase::goaway_received() const { |
+ return session_ != nullptr && session_->goaway_received(); |
+} |
+ |
+int QuicClientBase::GetNumSentClientHellos() { |
+ // If we are not actively attempting to connect, the session object |
+ // corresponds to the previous connection and should not be used. |
+ const int current_session_hellos = !connected_or_attempting_connect_ |
+ ? 0 |
+ : session_->GetNumSentClientHellos(); |
+ return num_sent_client_hellos_ + current_session_hellos; |
+} |
+ |
+void QuicClientBase::UpdateStats() { |
+ num_sent_client_hellos_ += session()->GetNumSentClientHellos(); |
+ if (session()->error() == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) { |
+ ++num_stateless_rejects_received_; |
+ } |
+} |
+ |
+QuicErrorCode QuicClientBase::connection_error() const { |
+ // Return the high-level error if there was one. Otherwise, return the |
+ // connection error from the last session. |
+ if (connection_error_ != QUIC_NO_ERROR) { |
+ return connection_error_; |
+ } |
+ if (session_.get() == nullptr) { |
+ return QUIC_NO_ERROR; |
+ } |
+ return session_->error(); |
+} |
+ |
+QuicConnectionId QuicClientBase::GetNextConnectionId() { |
+ QuicConnectionId server_designated_id = GetNextServerDesignatedConnectionId(); |
+ return server_designated_id ? server_designated_id |
+ : GenerateNewConnectionId(); |
+} |
+ |
+QuicConnectionId QuicClientBase::GetNextServerDesignatedConnectionId() { |
+ QuicCryptoClientConfig::CachedState* cached = |
+ crypto_config_.LookupOrCreate(server_id_); |
+ // If the cached state indicates that we should use a server-designated |
+ // connection ID, then return that connection ID. |
+ CHECK(cached != nullptr) << "QuicClientCryptoConfig::LookupOrCreate returned " |
+ << "unexpected nullptr."; |
+ return cached->has_server_designated_connection_id() |
+ ? cached->GetNextServerDesignatedConnectionId() |
+ : 0; |
+} |
+ |
+QuicConnectionId QuicClientBase::GenerateNewConnectionId() { |
+ return QuicRandom::GetInstance()->RandUint64(); |
+} |
+ |
+} // namespace tools |
+} // namespace net |