blob: 336ca142439e28ed4e9b8aca3cb0ebbce9ab0748 [file] [log] [blame]
QUICHE teamc9b2cec2019-01-07 17:54:15 -05001// Copyright (c) 2017 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/quartc/quartc_factory.h"
6
7#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
QUICHE team2bfc7542019-02-26 14:36:06 -05008#include "net/third_party/quiche/src/quic/core/quic_utils.h"
9#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h"
10#include "net/third_party/quiche/src/quic/core/tls_server_handshaker.h"
QUICHE teamc9b2cec2019-01-07 17:54:15 -050011#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
12#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
QUICHE team2bfc7542019-02-26 14:36:06 -050013#include "net/third_party/quiche/src/quic/quartc/quartc_connection_helper.h"
14#include "net/third_party/quiche/src/quic/quartc/quartc_crypto_helpers.h"
QUICHE teamc9b2cec2019-01-07 17:54:15 -050015#include "net/third_party/quiche/src/quic/quartc/quartc_session.h"
16
17namespace quic {
18
19QuartcFactory::QuartcFactory(const QuartcFactoryConfig& factory_config)
20 : alarm_factory_(factory_config.alarm_factory),
QUICHE team2bfc7542019-02-26 14:36:06 -050021 clock_(factory_config.clock),
22 connection_helper_(QuicMakeUnique<QuartcConnectionHelper>(clock_)),
23 compressed_certs_cache_(QuicMakeUnique<QuicCompressedCertsCache>(
24 QuicCompressedCertsCache::kQuicCompressedCertsCacheSize)),
25 stream_helper_(QuicMakeUnique<QuartcCryptoServerStreamHelper>()) {}
QUICHE teamc9b2cec2019-01-07 17:54:15 -050026
QUICHE team2bfc7542019-02-26 14:36:06 -050027std::unique_ptr<QuartcSession> QuartcFactory::CreateQuartcClientSession(
28 const QuartcSessionConfig& quartc_session_config,
29 QuicStringPiece server_crypto_config) {
QUICHE teamc9b2cec2019-01-07 17:54:15 -050030 DCHECK(quartc_session_config.packet_transport);
31
QUICHE teamc9b2cec2019-01-07 17:54:15 -050032 // QuartcSession will eventually own both |writer| and |quic_connection|.
33 auto writer =
34 QuicMakeUnique<QuartcPacketWriter>(quartc_session_config.packet_transport,
35 quartc_session_config.max_packet_size);
36
QUICHE team2bfc7542019-02-26 14:36:06 -050037 // While the QuicConfig is not directly used by the connection, creating it
38 // also sets flag values which must be set before creating the connection.
39 QuicConfig quic_config = CreateQuicConfig(quartc_session_config);
40 std::unique_ptr<QuicConnection> quic_connection =
41 CreateQuicConnection(Perspective::IS_CLIENT, writer.get());
42
43 return QuicMakeUnique<QuartcClientSession>(
44 std::move(quic_connection), quic_config, CurrentSupportedVersions(),
45 clock_, std::move(writer),
46 CreateCryptoClientConfig(quartc_session_config.pre_shared_key),
47 server_crypto_config);
48}
49
50QuicConfig CreateQuicConfig(const QuartcSessionConfig& quartc_session_config) {
51 // TODO(b/124398962): Figure out a better way to initialize QUIC flags.
52 // Creating a config shouldn't have global side-effects on flags. However,
53 // this has the advantage of ensuring that flag values stay in sync with the
54 // options requested by configs, so simply splitting the config and flag
55 // settings doesn't seem preferable.
56
QUICHE teamc9b2cec2019-01-07 17:54:15 -050057 // Fixes behavior of StopReading() with level-triggered stream sequencers.
58 SetQuicReloadableFlag(quic_stop_reading_when_level_triggered, true);
59
60 // Fix b/110259444.
61 SetQuicReloadableFlag(quic_fix_spurious_ack_alarm, true);
62
QUICHE team2bfc7542019-02-26 14:36:06 -050063 // Enable version 46+ to enable SendMessage API and 'quic bit' per draft 17.
QUICHE teamdc5ce1a2019-01-30 16:01:47 -050064 SetQuicReloadableFlag(quic_enable_version_46, true);
QUICHE teamc9b2cec2019-01-07 17:54:15 -050065
66 // Fix for inconsistent reporting of crypto handshake.
67 SetQuicReloadableFlag(quic_fix_has_pending_crypto_data, true);
68
69 // Ensure that we don't drop data because QUIC streams refuse to buffer it.
70 // TODO(b/120099046): Replace this with correct handling of WriteMemSlices().
71 SetQuicFlag(&FLAGS_quic_buffered_data_threshold,
72 std::numeric_limits<int>::max());
73
74 // TODO(b/117157454): Perform version negotiation for Quartc outside of
75 // QuicSession/QuicConnection. Currently default of
76 // gfe2_restart_flag_quic_no_server_conn_ver_negotiation2 is false,
77 // but we fail blueprint test that sets all QUIC flags to true.
78 //
79 // Forcing flag to false to pass blueprint tests, but eventually we'll have
80 // to implement negotiation outside of QuicConnection.
81 SetQuicRestartFlag(quic_no_server_conn_ver_negotiation2, false);
82
QUICHE teamc9b2cec2019-01-07 17:54:15 -050083 QuicTagVector copt;
84 copt.push_back(kNSTP);
85
86 // Enable and request QUIC to include receive timestamps in ACK frames.
87 SetQuicReloadableFlag(quic_send_timestamps, true);
88 copt.push_back(kSTMP);
89
90 // Enable ACK_DECIMATION_WITH_REORDERING. It requires ack_decimation to be
91 // false.
92 SetQuicReloadableFlag(quic_enable_ack_decimation, false);
93 copt.push_back(kAKD2);
94
95 // Use unlimited decimation in order to reduce number of unbundled ACKs.
96 copt.push_back(kAKDU);
97
98 // Enable time-based loss detection.
99 copt.push_back(kTIME);
100
QUICHE teamc9b2cec2019-01-07 17:54:15 -0500101 // Note: flag settings have no effect for Exoblaze builds since
102 // SetQuicReloadableFlag() gets stubbed out.
103 SetQuicReloadableFlag(quic_bbr_less_probe_rtt, true); // Enable BBR6,7,8.
104 SetQuicReloadableFlag(quic_unified_iw_options, true); // Enable IWXX opts.
105 SetQuicReloadableFlag(quic_bbr_slower_startup3, true); // Enable BBQX opts.
106 SetQuicReloadableFlag(quic_bbr_flexible_app_limited, true); // Enable BBR9.
107 copt.push_back(kBBR3); // Stay in low-gain until in-flight < BDP.
108 copt.push_back(kBBR5); // 40 RTT ack aggregation.
109 copt.push_back(kBBR6); // Use a 0.75 * BDP cwnd during PROBE_RTT.
110 copt.push_back(kBBR8); // Skip PROBE_RTT if app-limited.
111 copt.push_back(kBBR9); // Ignore app-limited if enough data is in flight.
112 copt.push_back(kBBQ1); // 2.773 pacing gain in STARTUP.
113 copt.push_back(kBBQ2); // 2.0 CWND gain in STARTUP.
114 copt.push_back(kBBQ4); // 0.75 pacing gain in DRAIN.
115 copt.push_back(k1RTT); // Exit STARTUP after 1 RTT with no gains.
116 copt.push_back(kIW10); // 10-packet (14600 byte) initial cwnd.
117
118 if (!quartc_session_config.enable_tail_loss_probe) {
119 copt.push_back(kNTLP);
120 }
121
QUICHE teamc9b2cec2019-01-07 17:54:15 -0500122 // TODO(b/112192153): Test and possible enable slower startup when pipe
123 // filling is ready to use. Slower startup is kBBRS.
124
125 QuicConfig quic_config;
126
127 // Use the limits for the session & stream flow control. The default 16KB
128 // limit leads to significantly undersending (not reaching BWE on the outgoing
129 // bitrate) due to blocked frames, and it leads to high latency (and one-way
130 // delay). Setting it to its limits is not going to cause issues (our streams
131 // are small generally, and if we were to buffer 24MB it wouldn't be the end
132 // of the world). We can consider setting different limits in future (e.g. 1MB
133 // stream, 1.5MB session). It's worth noting that on 1mbps bitrate, limit of
134 // 24MB can capture approx 4 minutes of the call, and the default increase in
135 // size of the window (half of the window size) is approximately 2 minutes of
136 // the call.
137 quic_config.SetInitialSessionFlowControlWindowToSend(
138 kSessionReceiveWindowLimit);
139 quic_config.SetInitialStreamFlowControlWindowToSend(
140 kStreamReceiveWindowLimit);
141 quic_config.SetConnectionOptionsToSend(copt);
142 quic_config.SetClientConnectionOptions(copt);
143 if (quartc_session_config.max_time_before_crypto_handshake >
144 QuicTime::Delta::Zero()) {
145 quic_config.set_max_time_before_crypto_handshake(
146 quartc_session_config.max_time_before_crypto_handshake);
147 }
148 if (quartc_session_config.max_idle_time_before_crypto_handshake >
149 QuicTime::Delta::Zero()) {
150 quic_config.set_max_idle_time_before_crypto_handshake(
151 quartc_session_config.max_idle_time_before_crypto_handshake);
152 }
153 if (quartc_session_config.idle_network_timeout > QuicTime::Delta::Zero()) {
154 quic_config.SetIdleNetworkTimeout(
155 quartc_session_config.idle_network_timeout,
156 quartc_session_config.idle_network_timeout);
157 }
158
159 // The ICE transport provides a unique 5-tuple for each connection. Save
160 // overhead by omitting the connection id.
161 quic_config.SetBytesForConnectionIdToSend(0);
162
163 // Allow up to 1000 incoming streams at once. Quartc streams typically contain
164 // one audio or video frame and close immediately. However, when a video frame
165 // becomes larger than one packet, there is some delay between the start and
166 // end of each stream. The default maximum of 100 only leaves about 1 second
167 // of headroom (Quartc sends ~30 video frames per second) before QUIC starts
168 // to refuse incoming streams. Back-pressure should clear backlogs of
169 // incomplete streams, but targets 1 second for recovery. Increasing the
170 // number of open streams gives sufficient headroom to recover before QUIC
171 // refuses new streams.
172 quic_config.SetMaxIncomingDynamicStreamsToSend(1000);
QUICHE team2bfc7542019-02-26 14:36:06 -0500173
174 return quic_config;
QUICHE teamc9b2cec2019-01-07 17:54:15 -0500175}
176
177std::unique_ptr<QuicConnection> QuartcFactory::CreateQuicConnection(
178 Perspective perspective,
179 QuartcPacketWriter* packet_writer) {
QUICHE team2bfc7542019-02-26 14:36:06 -0500180 // |dummy_id| and |dummy_address| are used because Quartc network layer will
181 // not use these two.
QUICHE teamc9b2cec2019-01-07 17:54:15 -0500182 char connection_id_bytes[sizeof(uint64_t)] = {};
QUICHE team2bfc7542019-02-26 14:36:06 -0500183 QuicConnectionId dummy_id = QuicConnectionId(
184 static_cast<char*>(connection_id_bytes), sizeof(connection_id_bytes));
185 QuicSocketAddress dummy_address(QuicIpAddress::Any4(), /*port=*/0);
186 return quic::CreateQuicConnection(
187 dummy_id, dummy_address, connection_helper_.get(), alarm_factory_,
188 packet_writer, perspective, CurrentSupportedVersions());
QUICHE teamc9b2cec2019-01-07 17:54:15 -0500189}
190
QUICHE team2bfc7542019-02-26 14:36:06 -0500191std::unique_ptr<QuicConnection> CreateQuicConnection(
192 QuicConnectionId connection_id,
193 const QuicSocketAddress& peer_address,
194 QuicConnectionHelperInterface* connection_helper,
195 QuicAlarmFactory* alarm_factory,
196 QuicPacketWriter* packet_writer,
197 Perspective perspective,
198 ParsedQuicVersionVector supported_versions) {
199 auto quic_connection = QuicMakeUnique<QuicConnection>(
200 connection_id, peer_address, connection_helper, alarm_factory,
201 packet_writer,
202 /*owns_writer=*/false, perspective, supported_versions);
QUICHE teamc9b2cec2019-01-07 17:54:15 -0500203
QUICHE team2bfc7542019-02-26 14:36:06 -0500204 QuicSentPacketManager& sent_packet_manager =
205 quic_connection->sent_packet_manager();
QUICHE teamc9b2cec2019-01-07 17:54:15 -0500206
QUICHE team2bfc7542019-02-26 14:36:06 -0500207 // Default delayed ack time is 25ms.
208 // If data packets are sent less often (e.g. because p-time was modified),
209 // we would force acks to be sent every 25ms regardless, increasing
210 // overhead. Since generally we guarantee a packet every 20ms, changing
211 // this value should have miniscule effect on quality on good connections,
212 // but on poor connections, changing this number significantly reduced the
213 // number of ack-only packets.
214 // The p-time can go up to as high as 120ms, and when it does, it's
215 // when the low overhead is the most important thing. Ideally it should be
216 // above 120ms, but it cannot be higher than 0.5*RTO, which equals to 100ms.
217 sent_packet_manager.set_delayed_ack_time(
218 QuicTime::Delta::FromMilliseconds(100));
219
220 quic_connection->set_fill_up_link_during_probing(true);
221
222 // We start ack decimation after 15 packets. Typically, we would see
223 // 1-2 crypto handshake packets, one media packet, and 10 probing packets.
224 // We want to get acks for the probing packets as soon as possible,
225 // but we can start using ack decimation right after first probing completes.
226 // The default was to not start ack decimation for the first 100 packets.
227 quic_connection->set_min_received_before_ack_decimation(15);
228
229 return quic_connection;
QUICHE teamc9b2cec2019-01-07 17:54:15 -0500230}
231
232std::unique_ptr<QuartcFactory> CreateQuartcFactory(
233 const QuartcFactoryConfig& factory_config) {
234 return std::unique_ptr<QuartcFactory>(new QuartcFactory(factory_config));
235}
236
237} // namespace quic