blob: ef9f2e285879982945e07a29770a41fcd089720a [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2012 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/third_party/quiche/src/quic/core/http/quic_spdy_client_session.h"
6
vasilvv872e7a32019-03-12 16:42:44 -07007#include <string>
8
QUICHE teama6ef0a62019-03-07 20:34:33 -05009#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
10#include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.h"
11#include "net/third_party/quiche/src/quic/core/http/spdy_utils.h"
12#include "net/third_party/quiche/src/quic/core/quic_server_id.h"
13#include "net/third_party/quiche/src/quic/core/quic_utils.h"
14#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
15#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
16#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
17#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
18#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050019
20namespace quic {
21
22QuicSpdyClientSession::QuicSpdyClientSession(
23 const QuicConfig& config,
24 const ParsedQuicVersionVector& supported_versions,
25 QuicConnection* connection,
26 const QuicServerId& server_id,
27 QuicCryptoClientConfig* crypto_config,
28 QuicClientPushPromiseIndex* push_promise_index)
29 : QuicSpdyClientSessionBase(connection,
30 push_promise_index,
31 config,
32 supported_versions),
33 server_id_(server_id),
34 crypto_config_(crypto_config),
35 respect_goaway_(true) {}
36
37QuicSpdyClientSession::~QuicSpdyClientSession() = default;
38
39void QuicSpdyClientSession::Initialize() {
40 crypto_stream_ = CreateQuicCryptoStream();
41 QuicSpdyClientSessionBase::Initialize();
42}
43
44void QuicSpdyClientSession::OnProofValid(
45 const QuicCryptoClientConfig::CachedState& /*cached*/) {}
46
47void QuicSpdyClientSession::OnProofVerifyDetailsAvailable(
48 const ProofVerifyDetails& /*verify_details*/) {}
49
50bool QuicSpdyClientSession::ShouldCreateOutgoingBidirectionalStream() {
51 if (!crypto_stream_->encryption_established()) {
52 QUIC_DLOG(INFO) << "Encryption not active so no outgoing stream created.";
53 return false;
54 }
55 if (!GetQuicReloadableFlag(quic_use_common_stream_check) &&
renjietangd1d00852019-09-06 10:43:12 -070056 !VersionHasIetfQuicFrames(transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050057 if (GetNumOpenOutgoingStreams() >=
58 stream_id_manager().max_open_outgoing_streams()) {
59 QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. "
60 << "Already " << GetNumOpenOutgoingStreams() << " open.";
61 return false;
62 }
63 if (goaway_received() && respect_goaway_) {
64 QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. "
65 << "Already received goaway.";
66 return false;
67 }
68 return true;
69 }
70 if (goaway_received() && respect_goaway_) {
71 QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. "
72 << "Already received goaway.";
73 return false;
74 }
75 QUIC_RELOADABLE_FLAG_COUNT_N(quic_use_common_stream_check, 1, 2);
76 return CanOpenNextOutgoingBidirectionalStream();
77}
78
79bool QuicSpdyClientSession::ShouldCreateOutgoingUnidirectionalStream() {
80 QUIC_BUG << "Try to create outgoing unidirectional client data streams";
81 return false;
82}
83
84QuicSpdyClientStream*
85QuicSpdyClientSession::CreateOutgoingBidirectionalStream() {
86 if (!ShouldCreateOutgoingBidirectionalStream()) {
87 return nullptr;
88 }
89 std::unique_ptr<QuicSpdyClientStream> stream = CreateClientStream();
90 QuicSpdyClientStream* stream_ptr = stream.get();
91 ActivateStream(std::move(stream));
92 return stream_ptr;
93}
94
95QuicSpdyClientStream*
96QuicSpdyClientSession::CreateOutgoingUnidirectionalStream() {
97 QUIC_BUG << "Try to create outgoing unidirectional client data streams";
98 return nullptr;
99}
100
101std::unique_ptr<QuicSpdyClientStream>
102QuicSpdyClientSession::CreateClientStream() {
103 return QuicMakeUnique<QuicSpdyClientStream>(
104 GetNextOutgoingBidirectionalStreamId(), this, BIDIRECTIONAL);
105}
106
107QuicCryptoClientStreamBase* QuicSpdyClientSession::GetMutableCryptoStream() {
108 return crypto_stream_.get();
109}
110
111const QuicCryptoClientStreamBase* QuicSpdyClientSession::GetCryptoStream()
112 const {
113 return crypto_stream_.get();
114}
115
116void QuicSpdyClientSession::CryptoConnect() {
117 DCHECK(flow_controller());
118 crypto_stream_->CryptoConnect();
119}
120
121int QuicSpdyClientSession::GetNumSentClientHellos() const {
122 return crypto_stream_->num_sent_client_hellos();
123}
124
125int QuicSpdyClientSession::GetNumReceivedServerConfigUpdates() const {
126 return crypto_stream_->num_scup_messages_received();
127}
128
129bool QuicSpdyClientSession::ShouldCreateIncomingStream(QuicStreamId id) {
130 if (!connection()->connected()) {
131 QUIC_BUG << "ShouldCreateIncomingStream called when disconnected";
132 return false;
133 }
134 if (goaway_received() && respect_goaway_) {
135 QUIC_DLOG(INFO) << "Failed to create a new outgoing stream. "
136 << "Already received goaway.";
137 return false;
138 }
renjietangd1d00852019-09-06 10:43:12 -0700139 if (QuicUtils::IsClientInitiatedStreamId(transport_version(), id) ||
140 (VersionHasIetfQuicFrames(transport_version()) &&
QUICHE teama6ef0a62019-03-07 20:34:33 -0500141 QuicUtils::IsBidirectionalStreamId(id))) {
142 QUIC_LOG(WARNING) << "Received invalid push stream id " << id;
143 connection()->CloseConnection(
144 QUIC_INVALID_STREAM_ID,
145 "Server created non write unidirectional stream",
146 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
147 return false;
148 }
149 return true;
150}
151
152QuicSpdyStream* QuicSpdyClientSession::CreateIncomingStream(
renjietangbaea59c2019-05-29 15:08:14 -0700153 PendingStream* pending) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500154 QuicSpdyStream* stream =
renjietangbaea59c2019-05-29 15:08:14 -0700155 new QuicSpdyClientStream(pending, this, READ_UNIDIRECTIONAL);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500156 ActivateStream(QuicWrapUnique(stream));
157 return stream;
158}
159
160QuicSpdyStream* QuicSpdyClientSession::CreateIncomingStream(QuicStreamId id) {
161 if (!ShouldCreateIncomingStream(id)) {
162 return nullptr;
163 }
164 QuicSpdyStream* stream =
165 new QuicSpdyClientStream(id, this, READ_UNIDIRECTIONAL);
166 ActivateStream(QuicWrapUnique(stream));
167 return stream;
168}
169
170std::unique_ptr<QuicCryptoClientStreamBase>
171QuicSpdyClientSession::CreateQuicCryptoStream() {
172 return QuicMakeUnique<QuicCryptoClientStream>(
173 server_id_, this,
174 crypto_config_->proof_verifier()->CreateDefaultContext(), crypto_config_,
175 this);
176}
177
dschinazi17d42422019-06-18 16:35:07 -0700178bool QuicSpdyClientSession::IsAuthorized(const std::string& /*authority*/) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500179 return true;
180}
181
182} // namespace quic