// Copyright (c) 2012 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_spdy_client_session.h" #include "net/log/net_log_with_source.h" #include "net/quic/chromium/crypto/proof_verifier_chromium.h" #include "net/quic/core/crypto/crypto_protocol.h" #include "net/quic/core/quic_server_id.h" #include "net/quic/core/spdy_utils.h" #include "net/quic/platform/api/quic_bug_tracker.h" #include "net/quic/platform/api/quic_logging.h" #include "net/quic/platform/api/quic_ptr_util.h" #include "net/tools/quic/quic_spdy_client_stream.h" using std::string; namespace net { QuicSpdyClientSession::QuicSpdyClientSession( const QuicConfig& config, QuicConnection* connection, const QuicServerId& server_id, QuicCryptoClientConfig* crypto_config, QuicClientPushPromiseIndex* push_promise_index) : QuicSpdyClientSessionBase(connection, push_promise_index, config), server_id_(server_id), crypto_config_(crypto_config), respect_goaway_(true) {} QuicSpdyClientSession::~QuicSpdyClientSession() {} void QuicSpdyClientSession::Initialize() { crypto_stream_ = CreateQuicCryptoStream(); QuicSpdyClientSessionBase::Initialize(); } void QuicSpdyClientSession::OnProofValid( const QuicCryptoClientConfig::CachedState& /*cached*/) {} void QuicSpdyClientSession::OnProofVerifyDetailsAvailable( const ProofVerifyDetails& /*verify_details*/) {} bool QuicSpdyClientSession::ShouldCreateOutgoingDynamicStream() { if (!crypto_stream_->encryption_established()) { QUIC_DLOG(INFO) << "Encryption not active so no outgoing stream created."; return false; } if (GetNumOpenOutgoingStreams() >= max_open_outgoing_streams()) { QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. " << "Already " << GetNumOpenOutgoingStreams() << " open."; return false; } if (goaway_received() && respect_goaway_) { QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. " << "Already received goaway."; return false; } return true; } QuicSpdyClientStream* QuicSpdyClientSession::CreateOutgoingDynamicStream() { if (!ShouldCreateOutgoingDynamicStream()) { return nullptr; } std::unique_ptr stream = CreateClientStream(); QuicSpdyClientStream* stream_ptr = stream.get(); ActivateStream(std::move(stream)); return stream_ptr; } std::unique_ptr QuicSpdyClientSession::CreateClientStream() { return QuicMakeUnique(GetNextOutgoingStreamId(), this); } QuicCryptoClientStreamBase* QuicSpdyClientSession::GetMutableCryptoStream() { return crypto_stream_.get(); } const QuicCryptoClientStreamBase* QuicSpdyClientSession::GetCryptoStream() const { return crypto_stream_.get(); } void QuicSpdyClientSession::CryptoConnect() { DCHECK(flow_controller()); crypto_stream_->CryptoConnect(); } int QuicSpdyClientSession::GetNumSentClientHellos() const { return crypto_stream_->num_sent_client_hellos(); } int QuicSpdyClientSession::GetNumReceivedServerConfigUpdates() const { return crypto_stream_->num_scup_messages_received(); } bool QuicSpdyClientSession::ShouldCreateIncomingDynamicStream(QuicStreamId id) { if (!connection()->connected()) { QUIC_BUG << "ShouldCreateIncomingDynamicStream called when disconnected"; return false; } if (goaway_received() && respect_goaway_) { QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. " << "Already received goaway."; return false; } if (id % 2 != 0) { QUIC_LOG(WARNING) << "Received invalid push stream id " << id; connection()->CloseConnection( QUIC_INVALID_STREAM_ID, "Server created odd numbered stream", ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); return false; } return true; } QuicSpdyStream* QuicSpdyClientSession::CreateIncomingDynamicStream( QuicStreamId id) { if (!ShouldCreateIncomingDynamicStream(id)) { return nullptr; } QuicSpdyStream* stream = new QuicSpdyClientStream(id, this); stream->CloseWriteSide(); ActivateStream(QuicWrapUnique(stream)); return stream; } std::unique_ptr QuicSpdyClientSession::CreateQuicCryptoStream() { return QuicMakeUnique( server_id_, this, new ProofVerifyContextChromium(0, NetLogWithSource()), crypto_config_, this); } bool QuicSpdyClientSession::IsAuthorized(const string& authority) { return true; } } // namespace net