Index: net/tools/quic/quic_client.cc |
diff --git a/net/tools/quic/quic_client.cc b/net/tools/quic/quic_client.cc |
index 18990fe13cb6d9066878d47640a3571bf5cac577..ed3585020a3dfa6b35b40f71494bf2ee4e0082a6 100644 |
--- a/net/tools/quic/quic_client.cc |
+++ b/net/tools/quic/quic_client.cc |
@@ -15,16 +15,12 @@ |
#include "net/base/net_util.h" |
#include "net/quic/crypto/quic_random.h" |
#include "net/quic/quic_connection.h" |
-#include "net/quic/quic_crypto_client_stream.h" |
#include "net/quic/quic_data_reader.h" |
#include "net/quic/quic_flags.h" |
#include "net/quic/quic_protocol.h" |
#include "net/quic/quic_server_id.h" |
-#include "net/tools/balsa/balsa_headers.h" |
-#include "net/tools/epoll_server/epoll_server.h" |
#include "net/tools/quic/quic_epoll_connection_helper.h" |
#include "net/tools/quic/quic_socket_utils.h" |
-#include "net/tools/quic/quic_spdy_client_stream.h" |
#include "net/tools/quic/spdy_balsa_utils.h" |
#ifndef SO_RXQ_OVFL |
@@ -60,9 +56,8 @@ QuicClient::QuicClient(IPEndPoint server_address, |
const QuicVersionVector& supported_versions, |
const QuicConfig& config, |
EpollServer* epoll_server) |
- : server_address_(server_address), |
- server_id_(server_id), |
- config_(config), |
+ : QuicClientBase(server_id, supported_versions, config), |
+ server_address_(server_address), |
local_port_(0), |
epoll_server_(epoll_server), |
fd_(-1), |
@@ -70,19 +65,14 @@ QuicClient::QuicClient(IPEndPoint server_address, |
initialized_(false), |
packets_dropped_(0), |
overflow_supported_(false), |
- supported_versions_(supported_versions), |
store_response_(false), |
- latest_response_code_(-1), |
- 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) {} |
+ latest_response_code_(-1) {} |
QuicClient::~QuicClient() { |
if (connected()) { |
session()->connection()->SendConnectionClose(QUIC_PEER_GOING_AWAY); |
} |
+ |
STLDeleteElements(&data_to_resend_on_connect_); |
STLDeleteElements(&data_sent_before_handshake_); |
@@ -90,24 +80,20 @@ QuicClient::~QuicClient() { |
} |
bool QuicClient::Initialize() { |
- DCHECK(!initialized_); |
- |
- num_sent_client_hellos_ = 0; |
- num_stateless_rejects_received_ = 0; |
- connection_error_ = QUIC_NO_ERROR; |
- connected_or_attempting_connect_ = false; |
+ QuicClientBase::Initialize(); |
// If an initial flow control window has not explicitly been set, then use the |
// same values that Chrome uses. |
const uint32 kSessionMaxRecvWindowSize = 15 * 1024 * 1024; // 15 MB |
const uint32 kStreamMaxRecvWindowSize = 6 * 1024 * 1024; // 6 MB |
- if (config_.GetInitialStreamFlowControlWindowToSend() == |
+ if (config()->GetInitialStreamFlowControlWindowToSend() == |
kMinimumFlowControlSendWindow) { |
- config_.SetInitialStreamFlowControlWindowToSend(kStreamMaxRecvWindowSize); |
+ config()->SetInitialStreamFlowControlWindowToSend(kStreamMaxRecvWindowSize); |
} |
- if (config_.GetInitialSessionFlowControlWindowToSend() == |
+ if (config()->GetInitialSessionFlowControlWindowToSend() == |
kMinimumFlowControlSendWindow) { |
- config_.SetInitialSessionFlowControlWindowToSend(kSessionMaxRecvWindowSize); |
+ config()->SetInitialSessionFlowControlWindowToSend( |
+ kSessionMaxRecvWindowSize); |
} |
epoll_server_->set_timeout_in_us(50 * 1000); |
@@ -121,17 +107,6 @@ bool QuicClient::Initialize() { |
return true; |
} |
-QuicClient::DummyPacketWriterFactory::DummyPacketWriterFactory( |
- QuicPacketWriter* writer) |
- : writer_(writer) {} |
- |
-QuicClient::DummyPacketWriterFactory::~DummyPacketWriterFactory() {} |
- |
-QuicPacketWriter* QuicClient::DummyPacketWriterFactory::Create( |
- QuicConnection* /*connection*/) const { |
- return writer_; |
-} |
- |
QuicClient::QuicDataToResend::QuicDataToResend(BalsaHeaders* headers, |
StringPiece body, |
bool fin) |
@@ -226,8 +201,8 @@ bool QuicClient::Connect() { |
} |
STLDeleteElements(&data_to_resend_on_connect_); |
} |
- if (session_.get() != nullptr && |
- session_->error() != QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) { |
+ if (session() != nullptr && |
+ session()->error() != QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) { |
// We've successfully created a session but we're not connected, and there |
// is no stateless reject to recover from. Give up trying. |
break; |
@@ -235,20 +210,12 @@ bool QuicClient::Connect() { |
} |
if (!connected() && |
GetNumSentClientHellos() > QuicCryptoClientStream::kMaxClientHellos && |
- session_ != nullptr && |
- session_->error() == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) { |
+ session() != nullptr && |
+ session()->error() == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) { |
// The overall connection failed due too many stateless rejects. |
- connection_error_ = QUIC_CRYPTO_TOO_MANY_REJECTS; |
+ set_connection_error(QUIC_CRYPTO_TOO_MANY_REJECTS); |
} |
- return session_->connection()->connected(); |
-} |
- |
-QuicClientSession* QuicClient::CreateQuicClientSession( |
- const QuicConfig& config, |
- QuicConnection* connection, |
- const QuicServerId& server_id, |
- QuicCryptoClientConfig* crypto_config) { |
- return new QuicClientSession(config, connection, server_id_, &crypto_config_); |
+ return session()->connection()->connected(); |
} |
void QuicClient::StartConnect() { |
@@ -259,45 +226,31 @@ void QuicClient::StartConnect() { |
DummyPacketWriterFactory factory(writer); |
- if (connected_or_attempting_connect_) { |
+ if (connected_or_attempting_connect()) { |
// Before we destroy the last session and create a new one, gather its stats |
// and update the stats for the overall connection. |
- num_sent_client_hellos_ += session_->GetNumSentClientHellos(); |
- if (session_->error() == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) { |
+ UpdateStats(); |
+ if (session()->error() == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) { |
// If the last error was due to a stateless reject, queue up the data to |
// be resent on the next successful connection. |
// TODO(jokulik): I'm a little bit concerned about ordering here. Maybe |
// we should just maintain one queue? |
- ++num_stateless_rejects_received_; |
DCHECK(data_to_resend_on_connect_.empty()); |
data_to_resend_on_connect_.swap(data_sent_before_handshake_); |
} |
} |
- session_.reset(CreateQuicClientSession( |
- config_, |
- new QuicConnection(GetNextConnectionId(), server_address_, helper_.get(), |
- factory, |
- /* owns_writer= */ false, Perspective::IS_CLIENT, |
- server_id_.is_https(), supported_versions_), |
- server_id_, &crypto_config_)); |
- if (initial_max_packet_length_ != 0) { |
- session_->connection()->set_max_packet_length(initial_max_packet_length_); |
- } |
+ CreateQuicClientSession(new QuicConnection( |
+ GetNextConnectionId(), server_address_, helper_.get(), factory, |
+ /* owns_writer= */ false, Perspective::IS_CLIENT, server_id().is_https(), |
+ supported_versions())); |
- // Reset |writer_| after |session_| so that the old writer outlives the old |
+ // Reset |writer_| after |session()| so that the old writer outlives the old |
// session. |
- if (writer_.get() != writer) { |
- writer_.reset(writer); |
- } |
- session_->Initialize(); |
- session_->CryptoConnect(); |
- connected_or_attempting_connect_ = true; |
-} |
- |
-bool QuicClient::EncryptionBeingEstablished() { |
- return !session_->IsEncryptionEstablished() && |
- session_->connection()->connected(); |
+ set_writer(writer); |
+ session()->Initialize(); |
+ session()->CryptoConnect(); |
+ set_connected_or_attempting_connect(true); |
} |
void QuicClient::Disconnect() { |
@@ -351,7 +304,7 @@ void QuicClient::SendRequest(const BalsaHeaders& headers, |
void QuicClient::MaybeAddQuicDataToResend(QuicDataToResend* data_to_resend) { |
DCHECK(FLAGS_enable_quic_stateless_reject_support); |
- if (session_->IsCryptoHandshakeConfirmed()) { |
+ if (session()->IsCryptoHandshakeConfirmed()) { |
// The handshake is confirmed. No need to continue saving requests to |
// resend. |
STLDeleteElements(&data_sent_before_handshake_); |
@@ -382,45 +335,21 @@ void QuicClient::SendRequestsAndWaitForResponse( |
while (WaitForEvents()) {} |
} |
-QuicSpdyClientStream* QuicClient::CreateReliableClientStream() { |
- if (!connected()) { |
- return nullptr; |
- } |
- |
- return session_->CreateOutgoingDynamicStream(); |
-} |
- |
-void QuicClient::WaitForStreamToClose(QuicStreamId id) { |
- DCHECK(connected()); |
- |
- while (connected() && !session_->IsClosedStream(id)) { |
- WaitForEvents(); |
- } |
-} |
- |
-void QuicClient::WaitForCryptoHandshakeConfirmed() { |
- DCHECK(connected()); |
- |
- while (connected() && !session_->IsCryptoHandshakeConfirmed()) { |
- WaitForEvents(); |
- } |
-} |
- |
bool QuicClient::WaitForEvents() { |
DCHECK(connected()); |
epoll_server_->WaitForEventsAndExecuteCallbacks(); |
- DCHECK(session_ != nullptr); |
+ DCHECK(session() != nullptr); |
if (!connected() && |
- session_->error() == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) { |
+ session()->error() == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) { |
DCHECK(FLAGS_enable_quic_stateless_reject_support); |
DVLOG(1) << "Detected stateless reject while waiting for events. " |
<< "Attempting to reconnect."; |
Connect(); |
} |
- return session_->num_active_requests() != 0; |
+ return session()->num_active_requests() != 0; |
} |
bool QuicClient::MigrateSocket(const IPAddressNumber& new_host) { |
@@ -436,14 +365,12 @@ bool QuicClient::MigrateSocket(const IPAddressNumber& new_host) { |
} |
epoll_server_->RegisterFD(fd_, this, kEpollFlags); |
- session_->connection()->SetSelfAddress(client_address_); |
+ session()->connection()->SetSelfAddress(client_address_); |
QuicPacketWriter* writer = CreateQuicPacketWriter(); |
DummyPacketWriterFactory factory(writer); |
- if (writer_.get() != writer) { |
- writer_.reset(writer); |
- } |
- session_->connection()->SetQuicPacketWriter(writer, false); |
+ set_writer(writer); |
+ session()->connection()->SetQuicPacketWriter(writer, false); |
return true; |
} |
@@ -456,8 +383,8 @@ void QuicClient::OnEvent(int fd, EpollEvent* event) { |
} |
} |
if (connected() && (event->in_events & EPOLLOUT)) { |
- writer_->SetWritable(); |
- session_->connection()->OnCanWrite(); |
+ writer()->SetWritable(); |
+ session()->connection()->OnCanWrite(); |
} |
if (event->in_events & EPOLLERR) { |
DVLOG(1) << "Epollerr"; |
@@ -485,15 +412,6 @@ void QuicClient::OnClose(QuicDataStream* stream) { |
} |
} |
-bool QuicClient::connected() const { |
- return session_.get() && session_->connection() && |
- session_->connection()->connected(); |
-} |
- |
-bool QuicClient::goaway_received() const { |
- return session_ != nullptr && session_->goaway_received(); |
-} |
- |
size_t QuicClient::latest_response_code() const { |
LOG_IF(DFATAL, !store_response_) << "Response not stored!"; |
return latest_response_code_; |
@@ -509,49 +427,6 @@ const string& QuicClient::latest_response_body() const { |
return latest_response_body_; |
} |
-int QuicClient::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; |
-} |
- |
-QuicErrorCode QuicClient::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 QuicClient::GetNextConnectionId() { |
- QuicConnectionId server_designated_id = GetNextServerDesignatedConnectionId(); |
- return server_designated_id ? server_designated_id |
- : GenerateNewConnectionId(); |
-} |
- |
-QuicConnectionId QuicClient::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 QuicClient::GenerateNewConnectionId() { |
- return QuicRandom::GetInstance()->RandUint64(); |
-} |
- |
QuicEpollConnectionHelper* QuicClient::CreateQuicConnectionHelper() { |
return new QuicEpollConnectionHelper(epoll_server_); |
} |
@@ -587,8 +462,8 @@ bool QuicClient::ReadAndProcessPacket() { |
QuicEncryptedPacket packet(buf, bytes_read, false); |
IPEndPoint client_address(client_ip, client_address_.port()); |
- session_->connection()->ProcessUdpPacket( |
- client_address, server_address, packet); |
+ session()->connection()->ProcessUdpPacket(client_address, server_address, |
+ packet); |
return true; |
} |